/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher.webtml;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.DynamicAttributes;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.Dom4JDriver;
import de.innovationgate.utils.URLBuilder;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.utils.Zipper;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGContent;
import de.innovationgate.webgate.api.WGDatabase;
import de.innovationgate.webgate.api.WGDocument;
import de.innovationgate.webgate.api.WGException;
import de.innovationgate.webgate.api.WGPortlet;
import de.innovationgate.webgate.api.WGTMLModule;
import de.innovationgate.webgate.api.WGUnavailableException;
import de.innovationgate.wgpublisher.DeployerException;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.log.IncludeInformation;
import de.innovationgate.wgpublisher.log.WGARequestInformation;
import de.innovationgate.wgpublisher.webtml.utils.AjaxInfo;
import de.innovationgate.wgpublisher.webtml.utils.RootTagReceptor;
import de.innovationgate.wgpublisher.webtml.utils.TMLContext;
import de.innovationgate.wgpublisher.webtml.utils.TMLException;
import de.innovationgate.wgpublisher.webtml.utils.TMLObject;
import de.innovationgate.wgpublisher.webtml.utils.TMLOption;
import de.innovationgate.wgpublisher.webtml.utils.TMLPortlet;
import de.innovationgate.wgpublisher.webtml.utils.TMLSilentCancelException;
public class Include extends Base implements DynamicAttributes {
private String key;
private String ref;
private String name;
private String type;
private String mediakey;
private String designdb;
private String linkaction;
private String ajax;
private String keepoptions;
private String timeout;
private String encoding;
private String linkmedium;
private String tmlscope;
private String portletmode;
public static class Status extends BaseTagStatus implements RootTagReceptor {
String type;
String ref;
protected Root.Status rootTag;
private Set optionsToFilter;
private long _startTime;
boolean ajax;
private String designdb;
public TMLContext getChildTagContext() {
return childTMLContext;
}
public void setRootTagStatus(Root.Status root) {
rootTag = root;
}
@Override
public void setOption(String name, Object value, String scope) {
super.setOption(name, value, scope);
// Remove options set in include body from options to filter
if (optionsToFilter.contains(name)) {
optionsToFilter.remove(name);
}
}
public Set getOptionsToFilter() {
return optionsToFilter;
}
@Override
public void initAttributeDelegates(Base tag) {
Include incTag = (Include) tag;
this.type = incTag.getType();
this.ref = incTag.getRef();
this.designdb = incTag.getDesigndb();
super.initAttributeDelegates(tag);
}
}
@Override
public BaseTagStatus createTagStatus() {
return new Status();
}
public static final String TYPE_TML = "tml";
public static final String TYPE_STATICTML = "statictml";
public static final String TYPE_INNERLAYOUT = "innerlayout";
public static final String TYPE_TAGRESULT = "tagresult";
public static final String TYPE_URL = "url";
public static final String TYPE_PORTLET = "portlet";
public static final String ATTRIB_INCLUDEPARENT = Include.class.getName() + ":IncludeParent";
public static final String OPTION_PORTLET_TMLMODULE = "$portlettmlmodule";
public static final String OPTION_AJAX_DIVTAG_ID = "$ajaxdivtagid";
public void tmlEndTag() throws TMLException, WGAPIException {
Status status = (Status) getStatus();
WGDatabase database = this.getMainContext().getdocument().getDatabase();
// Set WebTML scope option
String scope = getTmlscope();
if (scope != null) {
status.setOption(Base.OPTION_WEBTML_SCOPE, scope, TMLOption.SCOPE_GLOBAL);
}
// Set link action option
String linkAction = this.getLinkaction();
if (linkAction != null) {
getStatus().setOption(OPTION_LINK_ACTION, linkAction, TMLOption.SCOPE_GLOBAL);
}
// Set option "body" by content of include tag
// (only when no option "body" already available that was set explicitly for this tag or is of global scope)
TMLOption bodyOption = (TMLOption) getStatus().getTagOptions().get("body");
if (bodyOption == null || (status.optionsToFilter.contains("body") && bodyOption.getScope().equals(TMLOption.SCOPE_LOCAL))) {
status.setOption("body", getResultString(), TMLOption.SCOPE_LOCAL);
status.optionsToFilter.remove("body");
}
// Prepare portlet includsion
if (status.type.equals(TYPE_PORTLET)) {
preparePortletInclusion();
// The portlet inclusion is internally handled like a normal TML module inclusion
status.type = TYPE_TML;
}
// Determine design db key
String designDBKey = getTMLContext().resolveDBKey(status.designdb);
// Perform individual include type
if (status.type.equals(TYPE_TML) || status.type.equals(TYPE_INNERLAYOUT)) {
performTMLInclude(status.type, database, designDBKey);
}
else if (status.type.equals(TYPE_STATICTML)) {
performStaticTMLInclude(designDBKey);
}
else if (status.type.equals(TYPE_TAGRESULT)) {
BaseTagStatus tag = this.getTagStatusById(status.ref);
if (tag != null) {
this.setResult(tag.result);
} else {
this.addWarning("Could not find tag by id: " + status.ref);
}
if (getTMLContext().getwgacore().isProfilingEnabled()) {
HttpServletRequest request = getTMLContext().getrequest();
if (request != null) {
WGARequestInformation info = (WGARequestInformation) request.getAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME);
if (info != null) {
long duration = System.currentTimeMillis() - status._startTime;
IncludeInformation includeInfo = new IncludeInformation(getType(), status.ref, duration);
info.getIncludes().add(includeInfo);
}
}
}
}
else if (status.type.equals(TYPE_URL)) {
performURLInclude();
}
}
private void performURLInclude() throws TMLException {
Status status = (Status) getStatus();
try {
HttpClient client = new HttpClient();
HttpMethodParams methodParams = new HttpMethodParams();
methodParams.setSoTimeout(Integer.parseInt(getTimeout()));
methodParams.setVersion(HttpVersion.HTTP_1_1);
GetMethod getMethod = new GetMethod();
String ref = status.ref;
getMethod.setURI(new URI(ref, false));
getMethod.setParams(methodParams);
getMethod.setFollowRedirects(true);
int httpStatus = client.executeMethod(getMethod);
if (httpStatus != HttpServletResponse.SC_OK) {
throw new TMLException("Response status " + httpStatus + " (" + getMethod.getStatusText() + ") for included URL " + ref, true);
}
String encoding = getEncoding();
if (encoding != null) {
Reader reader = new InputStreamReader(getMethod.getResponseBodyAsStream(), encoding);
String contents = WGUtils.readString(reader);
this.setResult(contents);
}
else {
this.setResult(getMethod.getResponseBodyAsString());
}
} catch (java.io.IOException exc) {
log.error("Exception including url", exc);
this.addWarning("Exception while including url: " + exc.getMessage());
}
if (getTMLContext().getwgacore().isProfilingEnabled()) {
HttpServletRequest request = getTMLContext().getrequest();
if (request != null) {
WGARequestInformation info = (WGARequestInformation) request.getAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME);
if (info != null) {
long duration = System.currentTimeMillis() - status._startTime;
IncludeInformation includeInfo = new IncludeInformation(getType(), status.ref, duration);
info.getIncludes().add(includeInfo);
}
}
}
}
private void performStaticTMLInclude(String designDB) throws TMLException {
Status status = (Status) getStatus();
// Locate resource
String tmlName = status.ref;
if( tmlName == null || tmlName.equals("") ){
throw new TMLException("Could not retrieve result of included static resource. No reference given.");
}
String jspPath = "/static/tml/" + tmlName + ".jsp";
// Perform include
String oldDesignDB = (String) getOption(Base.OPTION_DESIGNDB);
this.pageContext.setAttribute(ATTRIB_INCLUDEPARENT, status, PageContext.REQUEST_SCOPE);
getStatus().setOption(Base.OPTION_DESIGNDB, designDB, null);
try {
this.pageContext.include(jspPath);
}
catch (Exception e) {
throw new TMLException("Error executing static tml module \"" + tmlName + "\"", e, false);
}
finally {
this.pageContext.setAttribute(ATTRIB_INCLUDEPARENT, null, PageContext.REQUEST_SCOPE);
getStatus().setOption(Base.OPTION_DESIGNDB, oldDesignDB, null);
}
// Import the included root tag result
if (status.rootTag != null) {
this.setResult(status.rootTag.result);
status.rootTag.result = null;
} else {
throw new TMLException("Could not retrieve result of included static resource: " + tmlName);
}
if (getTMLContext().getwgacore().isProfilingEnabled()) {
HttpServletRequest request = getTMLContext().getrequest();
if (request != null) {
WGARequestInformation info = (WGARequestInformation) request.getAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME);
if (info != null) {
long duration = System.currentTimeMillis() - status._startTime;
IncludeInformation includeInfo = new IncludeInformation(getType(), status.ref, duration);
info.getIncludes().add(includeInfo);
}
}
}
}
private void performTMLInclude(String type, WGDatabase database, String designDBKey) throws WGAPIException, TMLException {
Status status = (Status) getStatus();
String tmlResource = null;
String mediaKey = this.getMedium();
if (mediaKey == null) {
mediaKey = status.getMainMediaKey();
} else {
// change currentMediaKey-Option
status.setOption(OPTION_CURRENT_MEDIAKEY, mediaKey, null);
}
// Fetch the TML module to include
WGTMLModule tmllib;
if (type.equals(TYPE_INNERLAYOUT)) {
WGContent currentContent = this.getTMLContext().content();
if (currentContent.isDummy() || !currentContent.hasCompleteRelationships()) {
throw new TMLException("The inner layout of this content cannot be determined, bc. it is either a dummy document, or it doesnt have complete document relationships.");
}
tmllib = currentContent.getStructEntry().getInnerLayout(mediaKey);
designDBKey = currentContent.getDatabase().getDbReference();
if (tmllib == null || tmllib.isDummy()) {
throw new TMLException("Cannot find inner layout for doctype " + this.getTMLContext().content().getStructEntry().getContentType().getName());
}
}
else {
WGDatabase designdb = database;
if (designDBKey != null) {
try {
designdb = this.openContentDB(designDBKey);
}
catch (WGUnavailableException e1) {
}
catch (WGException e) {
throw new TMLException(e.getMessage(), true);
}
if (designdb == null || !designdb.isSessionOpen()) {
throw new TMLException("Cannot open design db: " + designDBKey, true);
}
}
tmllib = (WGTMLModule) designdb.getDesignObject(WGDocument.TYPE_TML, status.ref, mediaKey);
if (tmllib == null) {
throw new TMLException("Cannot find requested tml module: " + status.ref + " (" + mediaKey + ")");
}
}
// Locate the resource
try {
tmlResource = this.getDeployer().locateTmlResource(tmllib);
}
catch (DeployerException e1) {
throw new TMLException("Error deploying WebTML resource", e1, true);
}
if (tmlResource == null) {
throw new TMLException("Cannot locate requested tml module: " + tmllib.getName() + " (" + tmllib.getMediaKey() + ")");
}
// Do the include
this.pageContext.setAttribute(ATTRIB_INCLUDEPARENT, status, PageContext.REQUEST_SCOPE);
String oldDesignDB = (String) getOption(Base.OPTION_DESIGNDB);
status.setOption(Base.OPTION_DESIGNDB, designDBKey, null);
try {
this.pageContext.include(tmlResource);
}
catch (Exception e) {
throw new TMLException("Error executing tml module \"" + tmllib.getName() + "/" + tmllib.getMediaKey() + "\"", e, false);
}
finally {
this.pageContext.setAttribute(ATTRIB_INCLUDEPARENT, null, PageContext.REQUEST_SCOPE);
status.setOption(Base.OPTION_DESIGNDB, oldDesignDB, null);
}
// Transfer result from included root to this tag
if (status.rootTag != null) {
this.setResult(status.rootTag.result);
status.rootTag.result = null;
} else {
throw new TMLException("Could not retrieve result of included resource: " + tmlResource);
}
if (getTMLContext().getwgacore().isProfilingEnabled()) {
HttpServletRequest request = getTMLContext().getrequest();
if (request != null) {
WGARequestInformation info = (WGARequestInformation) request.getAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME);
if (info != null) {
long duration = System.currentTimeMillis() - status._startTime;
IncludeInformation includeInfo = new IncludeInformation(getType(), tmllib.getName(), duration);
includeInfo.setDesignDb(tmllib.getDatabase().getDbReference());
info.getIncludes().add(includeInfo);
}
}
}
}
private void preparePortletInclusion() throws TMLException, WGAPIException {
Status status = (Status) getStatus();
String type;
TMLPortlet parentPortlet = getTMLContext().getportlet();
if (parentPortlet == null) {
if (getTMLContext().isbotrequest()) {
throw new TMLSilentCancelException();
}
else {
throw new TMLException("Current user has no portlet registration");
}
}
String pKey = getKey();
String pName = getName();
// If no key direcly given try to fetch via portlet name
if (pKey == null && pName != null) {
pKey = parentPortlet.getPortletKeyForName(pName);
}
// Fetch registration info if key provided
WGPortlet pReg = null;
if (pKey != null) {
pReg = parentPortlet.getPortletRegistration(pKey);
}
// If reg not retrievable and auto registration info available try auto registration, else cancel
if (pReg == null) {
if (pName != null && status.ref != null) {
pKey = parentPortlet.registerportletforname(pName, status.designdb, status.ref, false);
pReg = parentPortlet.getPortletRegistration(pKey);
}
else {
if (pName != null) {
throw new TMLException("Portlet name not registered: " + pName, true);
}
else if (pKey != null) {
throw new TMLException("Portlet key not registered: " + pKey, true);
}
else {
throw new TMLException("No portlet key provided.", true);
}
}
}
// Check if registration matchtes the autoregister TML. If not, reregister with the given TML.
else if (status.ref != null) {
// If the registration has no design database specified we take the current design db (which is always equal)
if (pReg.getDesignDb() == null) {
pReg.setDesignDb(status.designdb);
}
if (!WGUtils.nullSafeEquals(status.ref, pReg.getDesign(), true) ||
(!WGUtils.nullSafeEquals(status.designdb, pReg.getDesignDb(), true))) {
pKey = parentPortlet.registerportletforname(pName, status.designdb, status.ref, true);
pReg = parentPortlet.getPortletRegistration(pKey);
}
}
// Prepare environment
status.setOption(Base.OPTION_PORTLET_NAMESPACE, pKey, null);
if (pReg.getDesignDb() != null) {
status.designdb = pReg.getDesignDb();
}
status.ref = getTMLContext().resolveDesignReference(pReg.getDesign());
// Update portlet event index information
TMLPortlet childPortlet = getTMLContext().getportlet();
childPortlet.prepareEventProcessing(this);
// set child tag context to portlet context if set
TMLContext portletContext = childPortlet.getcontext();
if (portletContext != null) {
setChildTagContext(portletContext);
}
// if ajax enabled
if (status.ajax) {
String uniquePortletID = pReg.getKey();
// create prefix buffer
StringBuffer prefix = new StringBuffer();
// create suffix buffer
StringBuffer suffix = new StringBuffer();
// set id as option, so tags from included module can retrieve it for rendering ajaxCall
status.setOption(OPTION_AJAX_DIVTAG_ID, uniquePortletID, null);
// set tmlModule as option, so tags from included module can retrieve the tmlmodulename
status.setOption(OPTION_PORTLET_TMLMODULE, pReg.getDesign(), null);
// create ajaxInfo
AjaxInfo ajaxInfo = new AjaxInfo(uniquePortletID);
try {
URLBuilder builder = new URLBuilder(getTMLContext().getrequest());
builder.removeParameter("$action");
java.net.URL url = builder.rebuild();
ajaxInfo.setQueryString(url.getQuery());
} catch (Exception e1) {
getTMLContext().addwarning("Unable to build request querystring for ajax environment.");
}
ajaxInfo.setTmlmodule(pReg.getDesign());
ajaxInfo.setDesignDB(pReg.getDesignDb() != null ? pReg.getDesignDb() : getDesigndb());
ajaxInfo.setMediaKey((String)this.getOption(OPTION_CURRENT_MEDIAKEY));
if (portletContext != null) {
ajaxInfo.setContextPath(portletContext.getpath());
} else {
ajaxInfo.setContextPath(this.getTMLContext().getpath());
}
ajaxInfo.setOptions(getStatus().getTagOptions());
if (getTMLContext().getprofile() != null) {
ajaxInfo.setSaveProfileOnEnd(getTMLContext().getprofile().isSavedOnEnd());
}
else {
ajaxInfo.setSaveProfileOnEnd(false);
}
ajaxInfo.setSuperform(getStatus().getRelevantForm());
// create javascript object with ajaxInfo
// serialize
String serAjaxInfo = new XStream(new Dom4JDriver()).toXML(ajaxInfo);
// zip
byte[] zipped = Zipper.zip(serAjaxInfo);
String encryptedAjaxInfo = "";
if (zipped != null) {
// encrypt
try {
encryptedAjaxInfo= this.getTMLContext().getwgacore().getDesEncrypter().encrypt(zipped);
}
catch (UnsupportedEncodingException e) {
throw new TMLException("Cannot render ajax enabled include because of unsupported encoding: " + e.getMessage(), true);
}
}
// iframe for form submit
// to prevent iframe from deletion by ajaxCall it has to be outside the divTag
// the iframe must be rendered with a blank-html page which exists on the wgaserver
// otherwise IE reacts with a security warning when wga runs on https
// @see http://support.microsoft.com/default.aspx?scid=kb;de;184960
/**
* WGA 4.0.7:
* WGA.ajax.action now generates iframes dynamicaly so static iframes are no longer needed
*
String blankIFrameURL = this.getWGPPath() + "/static/html/blank.htm";
prefix.append("<iframe name=\"$ajaxIFrame_" + uniquePortletID + "\" style=\"display:none\" src=\"" + blankIFrameURL + "\"></iframe>");
*
*/
// div tag for ajax paste
prefix.append("<div id=\"$ajaxDiv_" + uniquePortletID + "\">");
prefix.append("<div id=\"$ajaxContentDiv_" + uniquePortletID + "\">");
// javascript variable ajaxInfo
prefix.append("<script type=\"text/javascript\">");
prefix.append("var $ajaxInfo_" + uniquePortletID + " = '" + encryptedAjaxInfo + "';");
prefix.append("</script>");
suffix.append("</div></div>");
// set prefix and suffix
this.setPrefix(prefix.toString());
this.setSuffix(suffix.toString());
}
// register portlet on client side
String javaScriptPRegistration = getTMLContext().createJavaScriptPortletRegistration(pReg.getKey(), false);
if (javaScriptPRegistration != null) {
this.setPrefix(this.getPrefix() + javaScriptPRegistration);
}
// render events
String javaScriptPEvents = getTMLContext().createJavaScriptPortletEvents(pReg.getKey(), false);
if (javaScriptPEvents != null) {
this.setSuffix(this.getSuffix() + javaScriptPEvents);
}
// If an initial mode is determined set it
String portletMode = getPortletmode();
if (portletMode != null) {
getTMLContext().getportlet().setmode(portletMode);
}
}
public String getKey() {
return this.getTagAttributeValue("key", this.key, null);
}
public void setKey(String name) {
this.key = name;
}
/**
* Gets the name
* @return Returns a String
*/
public String getRef() {
return getTMLContext().resolveDesignReference(this.getTagAttributeValue("ref", ref, null));
}
/**
* Sets the name
* @param name The name to set
*/
public void setRef(String name) {
this.ref = name;
}
/**
* Gets the type
* @return Returns a String
*/
public String getType() {
return this.getTagAttributeValue("type", this.type, "tml");
}
/**
* Sets the type
* @param type The type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* Gets the mediakey
* @return Returns a String
*/
public String getMedium() {
String medium = this.getTagAttributeValue("medium", mediakey, null);
if (medium != null) {
getStatus().setOption(Base.OPTION_DEFAULT_MEDIAKEY, medium, null);
}
return medium;
}
/**
* Sets the mediakey
* @param mediakey The mediakey to set
*/
public void setMedium(String mediakey) {
this.mediakey = mediakey;
}
/**
* Returns the designdb.
* @return String
*/
public String getDesigndb() {
return this.getTagAttributeValue("designdb", designdb, getDesignDBKey());
}
/**
* Sets the designdb.
* @param designdb The designdb to set
*/
public void setDesigndb(String designdb) {
this.designdb = designdb;
}
/**
* Returns the linkaction.
* @return String
*/
public String getLinkaction() {
return getTMLContext().resolveDesignReference(this.getTagAttributeValue("linkaction", linkaction, null));
}
/**
* Sets the linkaction.
* @param linkaction The linkaction to set
*/
public void setLinkaction(String linkaction) {
this.linkaction = linkaction;
}
private String getAjax() {
return this.getTagAttributeValue("ajax", ajax, "false");
}
public void setAjax(String ajax) {
this.ajax = ajax;
}
public boolean isAjaxCall() {
if (getAjax().equalsIgnoreCase(ActionBase.AJAX_MODE_NO_PORTLET_REFRESH)) {
return true;
} else {
return stringToBoolean(getAjax());
}
}
public String getKeepoptions() {
return getTagAttributeValue("keepoptions", keepoptions, null);
}
public void setKeepoptions(String keepoptions) {
this.keepoptions = keepoptions;
}
public void tmlStartTag() throws TMLException {
Status status = (Status) getStatus();
status._startTime = System.currentTimeMillis();
status.ajax = stringToBoolean(getAjax());
// Keep names of options already available at start of include tag
// to be able to differ them from options set inside
// Build set of options to test for scope in included Root-Tag.
// Options to test are
// a) inherited from earlier tags (not set inside include tag)
// b) not included in attribute keepoptions
status.optionsToFilter = new HashSet(getStatus().getTagOptions().keySet());
String keepOptionsStr = getKeepoptions();
List keepOptions;
if (keepOptionsStr != null) {
keepOptions = WGUtils.deserializeCollection(keepOptionsStr, ",", true);
}
else {
keepOptions = new ArrayList();
}
status.optionsToFilter.removeAll(keepOptions);
// Set options injected by dynamic JSP attributes
Iterator options = status.dynamicOptions.entrySet().iterator();
while (options.hasNext()) {
Map.Entry option = (Map.Entry) options.next();
String optionName = (String) option.getKey();
String optionValue = getTagAttributeValue(optionName, (String) option.getValue(), null);
status.setOption(optionName, optionValue, TMLOption.SCOPE_GLOBAL);
if (status.optionsToFilter.contains(optionName)) {
status.optionsToFilter.remove(optionName);
}
}
// Set options by attributes
String linkMedium = getLinkmedium();
if (linkMedium != null) {
status.setOption(OPTION_LINK_MEDIUM, linkMedium, TMLOption.SCOPE_GLOBAL);
}
status.dynamicOptions.clear();
}
public String getName() {
return getTagAttributeValue("name", name, null);
}
public void setName(String name) {
this.name = name;
}
public void setDynamicAttribute(String uri, String localName, Object value) throws JspException {
if (localName.startsWith("o_")) {
String optionName = localName.substring(2);
Map<String,Object> dynAtts = (Map<String, Object>) getValue(TAGVALUE_DYNAMIC_ATTRIBUTES);
if (dynAtts == null) {
dynAtts = new HashMap<String,Object>();
setValue(TAGVALUE_DYNAMIC_ATTRIBUTES, dynAtts);
}
dynAtts.put(optionName, String.valueOf(value));
}
else {
addWarning("Attribute '" + localName + "' is unknown", false);
}
}
public String getTimeout() {
return getTagAttributeValue("timeout", timeout, "10000");
}
public void setTimeout(String timeout) {
this.timeout = timeout;
}
public String getEncoding() {
return getTagAttributeValue("encoding", encoding, null);
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getLinkmedium() {
return getTagAttributeValue("linkmedium", linkmedium, null);
}
public void setLinkmedium(String linkmedium) {
this.linkmedium = linkmedium;
}
public String getTmlscope() {
return getTagAttributeValue("tmlscope", tmlscope, null);
}
public void setTmlscope(String tmlscope) {
this.tmlscope = tmlscope;
}
public String getPortletmode() {
return getTagAttributeValue("portletmode", portletmode, null);
}
public void setPortletmode(String portletmode) {
this.portletmode = portletmode;
}
}