Java tutorial
/******************************************************************************* * 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.utils; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.collections.map.LinkedMap; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.util.URIUtil; import org.apache.log4j.Logger; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.search.highlight.Fragmenter; import org.apache.lucene.search.highlight.Highlighter; import org.apache.lucene.search.highlight.InvalidTokenOffsetsException; import org.apache.lucene.search.highlight.SimpleFragmenter; import org.apache.lucene.search.highlight.SimpleHTMLFormatter; import org.dom4j.Document; import org.xml.sax.SAXException; import com.google.gson.Gson; import de.innovationgate.utils.Base64; import de.innovationgate.utils.FormattingChain; import de.innovationgate.utils.FormattingException; import de.innovationgate.utils.ImageScaler; import de.innovationgate.utils.NullPlaceHolder; import de.innovationgate.utils.ObjectFormatter; import de.innovationgate.utils.TemporaryFile; import de.innovationgate.utils.TransientObjectWrapper; import de.innovationgate.utils.TransientWrappedMap; import de.innovationgate.utils.WGUtils; import de.innovationgate.webgate.api.SearchDetails; import de.innovationgate.webgate.api.WGAPIException; import de.innovationgate.webgate.api.WGArea; import de.innovationgate.webgate.api.WGCSSJSModule; import de.innovationgate.webgate.api.WGContent; import de.innovationgate.webgate.api.WGContentEventListener; import de.innovationgate.webgate.api.WGContentNavigator; import de.innovationgate.webgate.api.WGContentType; import de.innovationgate.webgate.api.WGDatabase; import de.innovationgate.webgate.api.WGDesignDocument; import de.innovationgate.webgate.api.WGDocument; import de.innovationgate.webgate.api.WGException; import de.innovationgate.webgate.api.WGExpressionException; import de.innovationgate.webgate.api.WGFactory; import de.innovationgate.webgate.api.WGFileAnnotations; import de.innovationgate.webgate.api.WGFileContainer; import de.innovationgate.webgate.api.WGFileDerivateMetaData; import de.innovationgate.webgate.api.WGHierarchicalDatabase; import de.innovationgate.webgate.api.WGIllegalArgumentException; import de.innovationgate.webgate.api.WGIllegalDataException; import de.innovationgate.webgate.api.WGIllegalStateException; import de.innovationgate.webgate.api.WGLanguage; import de.innovationgate.webgate.api.WGLanguageChooser; import de.innovationgate.webgate.api.WGPortlet; import de.innovationgate.webgate.api.WGPortletRegistry; import de.innovationgate.webgate.api.WGQueryException; import de.innovationgate.webgate.api.WGResultSet; import de.innovationgate.webgate.api.WGScriptModule; import de.innovationgate.webgate.api.WGStructEntry; import de.innovationgate.webgate.api.WGTMLModule; import de.innovationgate.webgate.api.WGUserAccess; import de.innovationgate.webgate.api.WGUserDetails; import de.innovationgate.webgate.api.WGUserProfile; import de.innovationgate.webgate.api.auth.AuthenticationModule; import de.innovationgate.webgate.api.auth.PasswordCachingAuthenticationModule; import de.innovationgate.webgate.api.workflow.WGNamedWorkflow; import de.innovationgate.webgate.api.workflow.WGWorkflow; import de.innovationgate.wga.common.CodeCompletion; import de.innovationgate.wga.common.Constants; import de.innovationgate.wga.common.beans.LuceneConfiguration; import de.innovationgate.wga.common.beans.LuceneIndexItemRule; import de.innovationgate.wga.common.beans.csconfig.v1.MediaKey; import de.innovationgate.wga.common.beans.csconfig.v1.PluginID; import de.innovationgate.wga.server.api.Design; import de.innovationgate.wga.server.api.TMLScript; import de.innovationgate.wga.server.api.TMLScript.ObjectType; import de.innovationgate.wga.server.api.UnavailableResourceException; import de.innovationgate.wga.server.api.WGA; import de.innovationgate.wga.server.api.tml.Context; import de.innovationgate.wga.server.api.tml.TMLPage; import de.innovationgate.wgpublisher.ClientHints; import de.innovationgate.wgpublisher.DBLoginInfo; import de.innovationgate.wgpublisher.PersonalisationManager; import de.innovationgate.wgpublisher.RenderServletRequest; import de.innovationgate.wgpublisher.RenderServletResponse; import de.innovationgate.wgpublisher.WGACore; import de.innovationgate.wgpublisher.WGADomain; import de.innovationgate.wgpublisher.WGAServerException; import de.innovationgate.wgpublisher.WGPDispatcher; import de.innovationgate.wgpublisher.auth.CSAuthModule; import de.innovationgate.wgpublisher.auth.Login; import de.innovationgate.wgpublisher.design.DesignResourceReference; import de.innovationgate.wgpublisher.expressions.ExpressionEngine; import de.innovationgate.wgpublisher.expressions.ExpressionEngineFactory; import de.innovationgate.wgpublisher.expressions.ExpressionResult; import de.innovationgate.wgpublisher.expressions.tmlscript.RhinoExpressionEngine; import de.innovationgate.wgpublisher.files.derivates.FileDerivateManager; import de.innovationgate.wgpublisher.files.derivates.FileDerivateManager.DerivateQuery; import de.innovationgate.wgpublisher.files.derivates.WGInvalidDerivateQueryException; import de.innovationgate.wgpublisher.filter.WGAFilter; import de.innovationgate.wgpublisher.filter.WGAFilter.RequestWrapper; import de.innovationgate.wgpublisher.lang.WebTMLLanguageChooser; import de.innovationgate.wgpublisher.lucene.LuceneManager; import de.innovationgate.wgpublisher.lucene.LuceneSearchDetails; import de.innovationgate.wgpublisher.mail.SmtpMail; import de.innovationgate.wgpublisher.plugins.WGAPlugin; import de.innovationgate.wgpublisher.problems.AdministrativeProblemType; import de.innovationgate.wgpublisher.problems.GlobalScope; import de.innovationgate.wgpublisher.problems.ProblemOccasion; import de.innovationgate.wgpublisher.problems.ProblemScope; import de.innovationgate.wgpublisher.problems.ProblemType; import de.innovationgate.wgpublisher.so.ManagedObject; import de.innovationgate.wgpublisher.so.ScopeObjectRegistry.ScopeObject; import de.innovationgate.wgpublisher.url.WGASpecificFileURLBuilder; import de.innovationgate.wgpublisher.url.WGAURLBuilder; import de.innovationgate.wgpublisher.webtml.Base; import de.innovationgate.wgpublisher.webtml.BaseTagStatus; import de.innovationgate.wgpublisher.webtml.ForEach; import de.innovationgate.wgpublisher.webtml.IterationTag; import de.innovationgate.wgpublisher.webtml.Query; import de.innovationgate.wgpublisher.webtml.actions.MasterCustomAction; import de.innovationgate.wgpublisher.webtml.actions.TMLAction; import de.innovationgate.wgpublisher.webtml.actions.TMLActionException; import de.innovationgate.wgpublisher.webtml.actions.TMLActionLink; import de.innovationgate.wgpublisher.webtml.env.IndependentDesignContext; import de.innovationgate.wgpublisher.webtml.env.IndependentTMLScriptEnvironment; import de.innovationgate.wgpublisher.webtml.env.IsolatedTMLContextEnvironment; import de.innovationgate.wgpublisher.webtml.env.WebTMLContextEnvironment; import de.innovationgate.wgpublisher.webtml.env.WebTMLDesignContext; import de.innovationgate.wgpublisher.webtml.form.TMLForm; import de.innovationgate.wgpublisher.webtml.form.TMLFormInfo; import de.innovationgate.wgpublisher.webtml.portlet.PortletEvent; import de.innovationgate.wgpublisher.webtml.portlet.TMLPortlet; import de.innovationgate.wgpublisher.webtml.portlet.TMLPortletStateStorage; import de.innovationgate.wgpublisher.webtml.utils.TMLContextEnvironment.RootEnvironmentUserData; /** * Object representing a TML context, i.e. a pointer on a WGA Content Document that is used somewhere inside WebTML. * This object is identical to the "this" object in TMLScript and provides the same functionalities. */ @CodeCompletion(methodMode = CodeCompletion.MODE_EXCLUDE, beanMode = CodeCompletion.BEAN_MODE_LOWERCASED, delegate = Context.class) public class TMLContext implements TMLObject, de.innovationgate.wga.server.api.tml.Context { public static final String SESSIONATTRIB_PROCESSCONTEXTS = "processContexts"; public static class Serialized { private String _path; public Serialized(String path) { _path = path; } public Object deserialize(TMLContext context) { return context.context(_path); } } public static class PersistentFormsMap extends TransientWrappedMap<String, TMLForm> { @Override protected Map<String, TMLForm> initWrappedMap() { return new ConcurrentHashMap<String, TMLForm>(); } } public static class WebTMLOccasion implements ProblemOccasion { @Override public ProblemScope getDefaultScope() { return GlobalScope.INSTANCE; } @Override public Class<? extends ProblemType> getDefaultType() { return AdministrativeProblemType.class; } @Override public Class<?> getDefaultRefClass() { return TMLContext.class; } @Override public boolean isClearedAutomatically() { return false; } } @CodeCompletion public static final String ACTIONID_DIVIDER = "/"; /** * Set as session attribute for tasks that execute master/async actions. * Contains the definition of the action that is executed in this task. */ @CodeCompletion public static final Object SESSIONATTRIB_ASYNCACTION = "AsyncAction"; @CodeCompletion public static ThreadLocal<LinkedList<TMLContext>> _threadMainContexts = new ThreadLocal<LinkedList<TMLContext>>(); public static TMLContext getThreadMainContext() { LinkedList<TMLContext> contexts = _threadMainContexts.get(); if (contexts != null && contexts.size() > 0) { return contexts.getLast(); } else { return null; } } public void makeThreadMainContext() { LinkedList<TMLContext> contexts = _threadMainContexts.get(); if (contexts == null) { contexts = new LinkedList<TMLContext>(); _threadMainContexts.set(contexts); } if ("true".equals(System.getProperty("de.innovationgate.wga.threadmaincontexts.verbose"))) { try { StackTraceElement[] elements = Thread.currentThread().getStackTrace(); getlog().info("Thread " + Thread.currentThread().hashCode() + " - Registering main context '" + getpath() + "' (" + System.identityHashCode(this) + ") at position " + contexts.size() + ", Stacktrace " + elements[2]); } catch (WGAPIException e) { // TODO Auto-generated catch block e.printStackTrace(); } } contexts.add(this); if (contexts.size() == 100) { getlog().warn("Size of main contexts list on thread '" + Thread.currentThread().getName() + "' exceeds 100 entries. The main contexts management is most likely leaking!"); } } public void removeThreadMainContext() { LinkedList<TMLContext> contexts = _threadMainContexts.get(); if ("true".equals(System.getProperty("de.innovationgate.wga.threadmaincontexts.verbose"))) { try { StackTraceElement[] elements = Thread.currentThread().getStackTrace(); getlog().info("Thread " + Thread.currentThread().hashCode() + " - Removing main context '" + getpath() + "' (" + System.identityHashCode(this) + ") at position " + (contexts.size() - 1) + ", Stacktrace " + elements[2]); } catch (WGAPIException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (contexts != null) { TMLContext lastContext = contexts.removeLast(); if (lastContext != this) { try { getlog().error( "Error in WebTML context management: Thread main context mismatch on removal. Removed: " + this.getpath() + " (" + System.identityHashCode(this) + "), In stack: " + lastContext.getpath() + " (" + System.identityHashCode(lastContext) + ")"); } catch (WGAPIException e) { } } } } public static void clearThreadMainContext() { LinkedList<TMLContext> contexts = _threadMainContexts.get(); if (contexts != null) { contexts.clear(); } } public static class ListVarContainer implements Serializable { private static final long serialVersionUID = -7274704419920612617L; private List<Object> _list; public ListVarContainer(List<Object> list) { _list = list; } /** * @return Returns the list. */ public List<Object> getList() { return _list; } } private TMLContextEnvironment _environment = null; private TMLDesignContext _designContext = null; public TMLContextEnvironment getEnvironment() { return _environment; } public void importEnvironmentData(TMLContext context, boolean includeIntrusiveData) throws TMLException { _environment.importEnvironmentData(context, includeIntrusiveData); } public void importEnvironmentData(TMLContext context) throws TMLException { importEnvironmentData(context, true); } public Map getActionRegistration() { return _environment.getActionRegistration(); } public Object callDefaultAction(TMLAction action, TMLActionLink link, Map<String, Object> objects) { try { TMLAction.DefaultAction defaultAction = TMLAction.getDefaultAction(action); if (defaultAction != null) { return defaultAction.call(action, this, link, objects); } else { addwarning("Unknown default action: " + link.getDefaultAction(), false); return null; } } catch (TMLException e) { addwarning("Error executing default action " + link.getDefaultAction() + ": " + e.getMessage(), false); return false; } catch (Exception e) { addwarning("Error executing default action " + link.getDefaultAction() + ": " + e.getMessage(), false); getlog().error("Error executing default action " + link.getDefaultAction(), e); return false; } } public ExpressionResult callCustomAction(TMLAction tmlAction, TMLActionLink actionLink, Map<String, Object> parentScopeObjects) throws WGAPIException { // Look if we must execute the action in a separate master action task. // We must do so if // a) we call a master action and are not already working under master rights // b) we call an async action and are not already in a master action task to execute this action boolean switchToMaster = tmlAction.isMaster() && !getdocument().getDatabase().getSessionContext().isMasterSession(); boolean switchToAsync = tmlAction.isAsync() && !WGUtils.nullSafeEquals( getdocument().getDatabase().getSessionContext().getAttribute(SESSIONATTRIB_ASYNCACTION), tmlAction); if (switchToMaster || switchToAsync) { MasterCustomAction masterAction = new MasterCustomAction(this, tmlAction, actionLink, parentScopeObjects); masterAction.start(); if (masterAction.getResult() != null) { return processActionResult(masterAction.getResult()); } else if (tmlAction.isAsync()) { return new ExpressionResult(null, false, false, null); } else { return new ExpressionResult(null, false, false, new WGExpressionException("Master action did not return result", tmlAction.getCode())); } } // Set params for (int idx = 0; idx < actionLink.getUnnamedParams().size(); idx++) { setvar("tmlparam" + (idx + 1), actionLink.getUnnamedParams().get(idx)); } // set additional objects and params. Keys must be lowercase so we have no doublettes in case-insensitive TMLScript Map<String, Object> additionalObjects = new HashMap<String, Object>(); if (parentScopeObjects != null) { Iterator<Map.Entry<String, Object>> entries = parentScopeObjects.entrySet().iterator(); while (entries.hasNext()) { Map.Entry<String, Object> entry = entries.next(); additionalObjects.put(String.valueOf(entry.getKey()).toLowerCase(), entry.getValue()); } } additionalObjects.put(RhinoExpressionEngine.PARAM_SCRIPTTIMEOUT, new Integer(tmlAction.getTimeout())); additionalObjects.put(RhinoExpressionEngine.PARAM_ACTIONDEFINITION, tmlAction); additionalObjects.put(TMLAction.OBJ_ACTION_PARAMS, actionLink.getUnnamedParams()); // Temporarily set design db to originating db of action (if not default action) boolean designDBSwitched = false; TMLContext actionContext = this; if (tmlAction.getOrigin() != TMLAction.ORIGIN_DEFAULT) { try { TMLDesignContext actionDesignContext = tmlAction.createDesignContext(this, _designContext); actionContext = new TMLContext(this, actionDesignContext); } catch (WGException e) { addwarning("Unable to switch design context bc. target database '" + tmlAction.getModuleDatabase() + "' cannot be opened", false); } } // Run action ExpressionEngine engine = ExpressionEngineFactory.getEngine(ExpressionEngineFactory.ENGINE_TMLSCRIPT); ExpressionResult result = engine.evaluateExpression(tmlAction.getCode(), actionContext, ExpressionEngine.TYPE_SCRIPT, additionalObjects); return processActionResult(result); } private ExpressionResult processActionResult(ExpressionResult result) throws WGExpressionException { if (result.isError()) { WGExpressionException exc = result.getException(); throw exc; } return result; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setvar(java.lang.String, java.lang.Object, boolean) */ @SuppressWarnings("unchecked") public void setvar(String name, Object value, boolean keepList) throws WGAPIException { if (this.document.getDatabase().hasFeature(WGDatabase.FEATURE_STORESVARS) && this.document.getDatabase() .getBooleanAttribute(WGACore.DBATTRIB_VARPROVISIONING, true) == true) { try { this.document.setItemValue(name, value); } catch (WGAPIException e) { getlog().warn( "Could not store WebTML variable as item on document bc. of exception. It will not be available in native expressions.", e); } } name = convertVarName(name); if (value instanceof List && keepList) { value = new ListVarContainer((List<Object>) value); } if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { getDesignContext().setLocalVarOnModule(name, value); } else { _environment.getPageVars().put(name, value); } } public String convertVarName(String name) { if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { return name; } else { return name.toLowerCase(); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getvar(java.lang.String) */ @Override public Object getvar(String name) throws WGAPIException { if (name == null) { return null; } name = convertVarName(name); if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { Object value = getDesignContext().retrieveLocalVar(name); if (value instanceof ListVarContainer) return ((ListVarContainer) value).getList(); if (!(value instanceof NullPlaceHolder)) { return value; } } Map vars = _environment.getPageVars(); if (vars.containsKey(name)) { Object value = vars.get(name); if (value instanceof ListVarContainer) return ((ListVarContainer) value).getList(); else return value; } return null; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getsessionvar(java.lang.String) */ @Override public Object getsessionvar(String name) { if (name == null) { return null; } name = convertVarName(name); Map<String, TransientObjectWrapper<Object>> sessionVars = _environment.getSessionVars(); if (sessionVars.containsKey(name)) { TransientObjectWrapper<Object> wrapper = sessionVars.get(name); if (wrapper != null) { Object value = wrapper.get(); if (value instanceof ListVarContainer) return ((ListVarContainer) value).getList(); return value; } } return null; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setvar(java.lang.String, java.lang.Object) */ @Override public void setvar(String name, Object value) throws WGAPIException { setvar(name, value, true); } /** * Tool method for the TMLScript engine defining the behaviour of setvar() short syntax * Will look for possible existing variables to update before setting a new variable * @param name Variable to set * @param value Value to Set * @throws WGAPIException */ public void updateOrSetVar(String name, Object value) throws WGException { String cname = convertVarName(name); // Look for portlet vars and portlet session vars of that name (B00005E12) String portletNameSpace = (String) option(Base.OPTION_PORTLET_NAMESPACE); if (portletNameSpace != null) { TMLPortlet portlet = getportlet(); if (portlet != null) { String pItemName = portlet.getVarPrefix() + cname; if (_environment.getPageVars().containsKey(pItemName)) { portlet.setvar(name, value); return; } Object pValue = portlet.retrieveSessionVar(name); if (pValue != null) { portlet.setsessionvar(name, value); return; } } } // Look for session var of that name if (_environment.getSessionVars().containsKey(cname)) { this.setsessionvar(cname, value); return; } // Compliance 7.2 - Look for local vars, then page vars of that name // Important to have this priority order for updating vars if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { Object localVarValue = getDesignContext().retrieveLocalVar(cname); if (!(localVarValue instanceof NullPlaceHolder)) { setvar(cname, value); return; } TMLPage page = WGA.get(this).tmlPage(); if (page.hasVar(cname)) { page.setVar(cname, value); return; } } // So we just set - (or maybe update, if compliance < 7.2) - a normal var this.setvar(cname, value); } private WGDocument document; private String role = null; private String lastError = null; /** * Constructor for the main context of a WebTML request * @param doc * @param tag */ @CodeCompletion public TMLContext(WGDocument doc, de.innovationgate.wgpublisher.webtml.Base tag) { this.document = doc; _environment = new WebTMLContextEnvironment(this, tag.getPageContext()); _designContext = new WebTMLDesignContext((WebTMLContextEnvironment) _environment, tag.getStatus(), null, null); if (this.document == null) { getwgacore().getLog().error("Request context with null content"); } } /** * Constructor to create new contextes that take environment and designcontext from a parent context * @param doc * @param parentContext */ public TMLContext(WGDocument doc, TMLContext parentContext) { this.document = doc; this._environment = parentContext.getEnvironment(); this._designContext = parentContext.getDesignContext(); if (this.document == null) { getwgacore().getLog().error("Request context with null content"); } } /** * Constructor to create clones of a context with a design context for a different WebTML tag * @param doc * @param parentContext */ public TMLContext(TMLContext parentContext, BaseTagStatus status) { this.document = parentContext.getdocument(); _environment = parentContext.getEnvironment(); if (!(_environment instanceof WebTMLContextEnvironment)) { throw new IllegalArgumentException("This constructor is only usable in WebTML context environments"); } _designContext = new WebTMLDesignContext((WebTMLContextEnvironment) _environment, status, status.getDesignDBKey(), status.getTMLModuleName()); if (this.document == null) { throw new IllegalArgumentException("Request context with null content"); } } /** * Constructor to create clones of a context with the custom design context of a WebTML action * @param doc * @param parentContext */ private TMLContext(TMLContext parentContext, TMLDesignContext designContext) { this.document = parentContext.getdocument(); _environment = parentContext.getEnvironment(); _designContext = designContext; if (this.document == null) { throw new IllegalArgumentException("Request context with null content"); } } public TMLContext(WGDocument doc, WGACore core, TMLUserProfile userProfile, TMLForm form, HttpServletRequest req, HttpServletResponse rsp, HttpSession session, TMLContext parentContext) { this.document = doc; // No environment given. This is a new independent TMLScript environmeent if (parentContext == null) { _environment = new IndependentTMLScriptEnvironment(this, core, userProfile, form, req, rsp, session); _designContext = new IndependentDesignContext((IndependentTMLScriptEnvironment) _environment, null, ""); } // Derived context. We will load vars of the given environment else { _environment = parentContext.getEnvironment(); _designContext = parentContext.getDesignContext(); } } @CodeCompletion public TMLContext(WGDocument doc, WGACore core, TMLUserProfile userProfile, TMLForm form) { this(doc, core, userProfile, form, null, null, null, null); } public TMLContext(WGDocument doc, WGACore core, TMLUserProfile userProfile, TMLForm form, HttpServletRequest req, HttpServletResponse rsp, HttpSession session) { this(doc, core, userProfile, form, req, rsp, session, null); } public TMLContext getmaincontext() { return _environment.getMainContext(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#item(java.lang.String) */ @Override public Object item(String name) throws WGAPIException { return item(name, Collections.<String, Object>emptyMap()); } public Object item(String name, Map<String, Object> params) throws WGAPIException { Object value = flattenList(retrieveItem(name, params), !getDesignContext().getVersionCompliance().isAtLeast(7, 2)); if (value instanceof NullPlaceHolder) { value = db().getNoItemBehaviour().getForTMLItem(); } return value; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#item(java.lang.String, java.lang.String) */ public Object item(String type, String name) throws WGAPIException { name = name.toLowerCase(); if (type.equals("content")) { return item(name); } else if (type.equals("profile")) { TMLUserProfile profile = getprofile(); if (profile == null) { addwarning("Current user has no profile", true); return ""; } return profile.item(name); } else if (type.equals("portlet")) { TMLPortlet portlet = getportlet(); if (portlet == null) { if (!isbotrequest()) { this.addwarning("Current user has no portlet registry", true); } return ""; } return portlet.item(name); } return ""; } public boolean isbotrequest() { TMLUserProfile profile = getprofile(); return (profile != null && profile.isdummy()); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#itemlist(java.lang.String, java.lang.String) */ public Object itemlist(String type, String name) throws WGAPIException { name = name.toLowerCase(); if (type.equals("content")) { return itemlist(name); } else if (type.equals("profile")) { TMLUserProfile profile = getprofile(); if (profile == null) { addwarning("Current user has no profile", true); return ""; } return profile.itemlist(name); } else if (type.equals("portlet")) { TMLPortlet portlet = getportlet(); if (portlet == null) { if (!isbotrequest()) { this.addwarning("Current user has no portlet registry", true); } return ""; } return portlet.itemlist(name); } return ""; } public WGDocument getdocument() { return document; } public boolean hasVariable(String name) { name = convertVarName(name); try { if (_environment.getPageVars().containsKey(name)) { return true; } if (_environment.getSessionVars().containsKey(name)) { return true; } if (!(_designContext.retrieveLocalVar(name) instanceof NullPlaceHolder)) { return true; } } catch (WGAPIException e) { addwarning("Exception testing for variable existence: " + name, false, e); } return false; } public boolean hasMappedItemValue(String name) { name = convertVarName(name); if (this.getMappedItemValue(name) == null) { return false; } else { return true; } } private Object retrieveItem(String name, Map<String, Object> params) throws WGAPIException { try { return new ItemExpression(this, name).retrieve(params, null, null); } catch (WGAPIException e) { throw e; } catch (WGException e) { throw new WGAPIException(e); } } protected Object retrieveVar(String name) throws WGAPIException { if (name == null) { return null; } String cname = convertVarName(name); Map<String, Object> pageVars = _environment.getPageVars(); // Portlet variables String portletNameSpace = (String) option(Base.OPTION_PORTLET_NAMESPACE); if (portletNameSpace != null) { TMLPortlet portlet = getportlet(); if (portlet != null) { // Portlet variables. Stored along with regular WebTML variables plus prefix String pName = portlet.getVarPrefix() + cname; if (pageVars.containsKey(pName)) { return pageVars.get(pName); } // Portlet session variables. Stored on the portlet session context, therefore retrieved via portlet object Object value = portlet.retrieveSessionVar(name); if (value != null) { return value; } } } // Local variables (since 7.2) if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { Object value = getDesignContext().retrieveLocalVar(cname); if (!(value instanceof NullPlaceHolder)) { return value; } } // Regular page (request) variables if (pageVars.containsKey(cname)) { return pageVars.get(cname); } // Session variables Map<String, TransientObjectWrapper<Object>> sessionVars = _environment.getSessionVars(); if (sessionVars.containsKey(cname)) { return sessionVars.get(cname).get(); } return new NullPlaceHolder(); } public static Object flattenList(Object object, boolean reduceList) { if (object == null) { return null; } if (object instanceof List) { if (!reduceList) { return object; } List<?> list = (List<?>) object; if (list.size() == 0) { return null; } else { return ((List<?>) object).get(0); } } else if (object instanceof ListVarContainer) { return ((ListVarContainer) object).getList(); } else { return object; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#itemlist(java.lang.String) */ @Override public List<Object> itemlist(String name) throws WGAPIException { return itemlist(name, Collections.<String, Object>emptyMap()); } public List<Object> itemlist(String name, Map<String, Object> params) throws WGAPIException { Object value = retrieveItem(name, params); if (value instanceof NullPlaceHolder) { return db().getNoItemBehaviour().getForTMLItemList(); } else { return toList(value); } } public Iterable<Object> itemiterable(String name) throws WGException { return itemiterable(name, Collections.<String, Object>emptyMap()); } public Iterable<Object> itemiterable(String name, Map<String, Object> params) throws WGException { Object value = retrieveItem(name, params); if (value instanceof NullPlaceHolder) { return db().getNoItemBehaviour().getForTMLItemList(); } else { return toIterable(value); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#highlightitem(java.lang.String, java.lang.String, java.lang.String) */ @CodeCompletion public String highlightitem(String name, String prefix, String suffix) throws WGAPIException { return highlightitem(name, prefix, suffix, null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#highlightitem(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @CodeCompletion public String highlightitem(String name, String prefix, String suffix, String encode) throws WGAPIException { if (name == null) { return null; } // lowercase name name = name.toLowerCase(); // retrieve itemtext String originalText = itemTextValue(name, encode); if (originalText == null) { return null; } if (!getwgacore().isLuceneEnabled()) { addwarning("Unable to highlight item '" + name + "' bc. lucene is not enabled."); return originalText; } // try to retrieve last lucene query for highlighting org.apache.lucene.search.Query query = (org.apache.lucene.search.Query) getrequest().getSession() .getAttribute(Query.SESSION_ATTRIBUTE_SIMPLIFIED_LUCENEQUERY); if (query == null) { // no query in session - highlighting not possible addwarning( "Lucene highlighting not possible because there is no query with enabled highlighting support"); return originalText; } // create htmlformatter to highlight fragments with "$HIGHLIGHT_PREFIX$", "$HIGHLIGHT_SUFFIX$" // these placeholders are later on replaced by the given prefix and suffix // this additional step is necessary to encode the fragment text properly // see F00004C66 String prefixPlaceholder = "$HIGHLIGHT_PREFIX$"; String suffixPlaceholder = "$HIGHLIGHT_SUFFIX$"; SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(prefixPlaceholder, suffixPlaceholder); // create highlighter Highlighter highlighter = getwgacore().getLuceneManager().createHighlighter(name, query, formatter); // create text to analyze LuceneConfiguration config = getwgacore().getLuceneManager() .retrieveLuceneConfig(content().getDatabase().getDbReference()); LuceneIndexItemRule rule = config.getMatchingItemRule(name); String analyzeText = rule.parseItemValue(originalText); // create tokenstream TokenStream tokenStream = getwgacore().getLuceneManager().createTokenStream(analyzeText, content()); // create fragmenter and set fragmentsize to itemText.length to ensure only one fragments with the whole itemText is returned Fragmenter fragmenter = new SimpleFragmenter(originalText.length() + 1); // if analyzeText.length == originalText.length we might get two fragments from lucene without the +1 (possible lucene bug) highlighter.setTextFragmenter(fragmenter); try { String highlighted = highlighter.getBestFragment(tokenStream, originalText); if (highlighted != null) { // replace highlight placeholders with correct prefix and suffix highlighted = WGUtils.strReplace(highlighted, prefixPlaceholder, prefix, true); highlighted = WGUtils.strReplace(highlighted, suffixPlaceholder, suffix, true); return highlighted; } } catch (IOException e) { addwarning("Unable to highlight item '" + name + "' bc. of exception '" + e.getMessage() + "'."); } catch (InvalidTokenOffsetsException e) { addwarning("Unable to highlight item '" + name + "' bc. of exception '" + e.getMessage() + "'."); } return originalText; } /** * returns a singleton list with metavalues highlighted (surrounded with given <prefix> and <suffix>) based uppon the last lucene query with highlight attribute set to true * if highlighting is not possible this method returns metalist(<name>); * @param name * @param prefix * @param suffix * @return list * @throws WGAPIException * @throws WGAPIException */ @CodeCompletion public List highlightMeta(String name, String prefix, String suffix) throws WGAPIException { return highlightMeta(name, prefix, suffix, null); } /** * returns a singleton list with metavalues highlighted (surrounded with given <prefix> and <suffix>) based uppon the last lucene query with highlight attribute set to true * if highlighting is not possible this method returns metalist(<name>); * @param name * @param prefix * @param suffix * @param encode * @return list * @throws WGAPIException */ @CodeCompletion public List highlightMeta(String name, String prefix, String suffix, String encode) throws WGAPIException { if (name == null) { return null; } String originalText = metaTextValue(name, encode); List<String> originalTextAsList = Collections.singletonList(originalText); if (!getwgacore().isLuceneEnabled()) { addwarning("Unable to highlight meta '" + name + "' bc. lucene is not enabled."); return originalTextAsList; } // try to retrieve last lucene query for highlighting org.apache.lucene.search.Query query = (org.apache.lucene.search.Query) getrequest().getSession() .getAttribute(Query.SESSION_ATTRIBUTE_SIMPLIFIED_LUCENEQUERY); if (query == null) { // no query in session - highlighting not possible return originalTextAsList; } // create htmlformatter to highlight fragments with "$HIGHLIGHT_PREFIX$", "$HIGHLIGHT_SUFFIX$" // these placeholders are later on replaced by the given prefix and suffix // this additional step is necessary to encode the fragment text properly String prefixPlaceholder = "$HIGHLIGHT_PREFIX$"; String suffixPlaceholder = "$HIGHLIGHT_SUFFIX$"; SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(prefixPlaceholder, suffixPlaceholder); // create highlighter Highlighter highlighter = getwgacore().getLuceneManager().createHighlighter(name.toUpperCase(), query, formatter); // create tokenstream TokenStream tokenStream = getwgacore().getLuceneManager().createTokenStream(originalText, content()); // create fragmenter and set fragmentsize to metaText.length to ensure only one fragments with the whole metaText is returned Fragmenter fragmenter = new SimpleFragmenter(originalText.length() + 1); // +1 is necessary here highlighter.setTextFragmenter(fragmenter); try { String highlighted = highlighter.getBestFragment(tokenStream, originalText); if (highlighted != null) { // replace highlight placeholders with correct prefix and suffix highlighted = WGUtils.strReplace(highlighted, prefixPlaceholder, prefix, true); highlighted = WGUtils.strReplace(highlighted, suffixPlaceholder, suffix, true); return Collections.singletonList(highlighted); } else { return originalTextAsList; } } catch (IOException e) { addwarning("Unable to highlight meta '" + name + "' bc. of exception '" + e.getMessage() + "'."); return originalTextAsList; } catch (InvalidTokenOffsetsException e) { addwarning("Unable to highlight meta '" + name + "' bc. of exception '" + e.getMessage() + "'."); return originalTextAsList; } } /** * retrieves a list of the best fragments from the given contentItem based upon the last lucene query with highlight attribute set to true * query hits are not highlighted in fragments * @param itemname the item fragements should be retrieved from * @param fragmentSize the number of characters for each fragment * @param maxFragments the maximum number of fragements returned * @return list of fragements (Strings) - if no lucene query present returns EMPTY_LIST * @throws WGAPIException */ @CodeCompletion public List bestfragments(String itemname, int fragmentSize, int maxFragments) throws WGAPIException { return bestfragments(itemname, fragmentSize, maxFragments, "", ""); } /** * retrieves a list of the best fragments from the given contentItem based upon the last lucene query with highlight attribute set to true * query hits are highlighted (surrounded by given <prefix> and <suffix>) in fragments * @param itemname the item fragements should be retrieved from * @param fragmentSize the number of characters for each fragment * @param maxFragments the maximum number of fragements returned * @param prefix the prefix for highlighting the search term in fragements * @param suffix the suffix for highlighting the search term in fragements * @return list of fragements (Strings) - if no lucene query present returns EMPTY_LIST * @throws WGAPIException */ @CodeCompletion public List bestfragments(String itemname, int fragmentSize, int maxFragments, String prefix, String suffix) throws WGAPIException { return bestfragments(itemname, fragmentSize, maxFragments, prefix, suffix, null); } /** * retrieves a list of the best fragments from the given contentItem based upon the last lucene query with highlight attribute set to true * query hits are highlighted (surrounded by given <prefix> and <suffix>) in fragments * @param itemname the item fragements should be retrieved from * @param fragmentSize the number of characters for each fragment * @param maxFragments the maximum number of fragements returned * @param prefix the prefix for highlighting the search term in fragements * @param suffix the suffix for highlighting the search term in fragements * @param encode encode each fragment in the given encoding - prefix and suffix will not be encoded * @return list of fragements (Strings) - if no lucene query present returns EMPTY_LIST * @throws WGAPIException */ @CodeCompletion public List bestfragments(String itemname, int fragmentSize, int maxFragments, String prefix, String suffix, String encode) throws WGAPIException { // check preconditions for highlighting if (itemname == null) { throw new WGIllegalArgumentException("Unable to retrieve best fragments for item 'null'."); } if (!getwgacore().isLuceneEnabled()) { addwarning("Unable to highlight item '" + itemname + "' bc. lucene is not enabled."); return Collections.EMPTY_LIST; } // try to retrieve last lucene query for highlighting org.apache.lucene.search.Query query = (org.apache.lucene.search.Query) getrequest().getSession() .getAttribute(Query.SESSION_ATTRIBUTE_SIMPLIFIED_LUCENEQUERY); if (query == null) { // no query in session - highlighting not possible return Collections.EMPTY_LIST; } // lowercase name itemname = itemname.toLowerCase(); // create htmlformatter to highlight fragments with "$HIGHLIGHT_PREFIX$", "$HIGHLIGHT_SUFFIX$" // these placeholders are later on replaced by the given prefix and suffix // this additional step is necessary to encode the fragment text properly // see B00004BBE String prefixPlaceholder = "$HIGHLIGHT_PREFIX$"; String suffixPlaceholder = "$HIGHLIGHT_SUFFIX$"; SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(prefixPlaceholder, suffixPlaceholder); // create highlighter Highlighter highlighter = getwgacore().getLuceneManager().createHighlighter(itemname, query, formatter); // retrieve itemtext String text = itemTextValue(itemname, "none"); if (text == null) { return Collections.EMPTY_LIST; } // remove html/xml from text // fragments should not contain html/xml bc. of design issues try { text = WGUtils.toPlainText(text, " ", false); // B000049EA // if the item value contains encoded html entities these entities has been converted to their characters // we should do an html encode for sure // text = WGUtils.encodeHTML(text); --> has side effects @see B00004BBE } catch (IOException e) { addwarning("Unable to highlight item '" + itemname + "' bc. of exception '" + e.getMessage() + "'."); return Collections.EMPTY_LIST; } // create tokenstream TokenStream tokenStream = getwgacore().getLuceneManager().createTokenStream(text, content()); // create fragmenter Fragmenter fragmenter = new SimpleFragmenter(fragmentSize); highlighter.setTextFragmenter(fragmenter); try { String[] highlighted = highlighter.getBestFragments(tokenStream, text, maxFragments); if (highlighted != null) { ArrayList list = new ArrayList(); for (int i = 0; i < highlighted.length; i++) { // B00004BBE // evtl. encode fragment String fragment = highlighted[i]; if (encode != null) { try { fragment = multiencode(encode, fragment); } catch (FormattingException e) { addwarning("Unable to highlight item '" + itemname + "' bc. of formating exception '" + e.getMessage() + "'."); return Collections.EMPTY_LIST; } } // B00004BBE // replace highlight placeholders with correct prefix and suffix fragment = WGUtils.strReplace(fragment, prefixPlaceholder, prefix, true); fragment = WGUtils.strReplace(fragment, suffixPlaceholder, suffix, true); list.add(fragment); } return list; } else { return Collections.EMPTY_LIST; } } catch (IOException e) { addwarning("Unable to highlight item '" + itemname + "' bc. of exception '" + e.getMessage() + "'."); return Collections.EMPTY_LIST; } catch (InvalidTokenOffsetsException e) { addwarning("Unable to highlight item '" + itemname + "' bc. of exception '" + e.getMessage() + "'."); return Collections.EMPTY_LIST; } } /** * removes the last lucene query from session * should be called when you are sure you do not need further highlighting of content items * for the last executed lucene query with highlight=="true" */ @CodeCompletion public void removelucenequery() { getrequest().getSession().removeAttribute(Query.SESSION_ATTRIBUTE_SIMPLIFIED_LUCENEQUERY); } /** * returns the itemvalue as text, concatenating eventual list elements and doing encoding * @param name Item name * @param Optional WebTML encoding. Use null to have none. * @return itemvalue as text, null if item is not found or itemvalue is null or itemvalues are no Strings * @throws WGAPIException */ private String itemTextValue(String name, String encode) throws WGAPIException { if (name == null) { return null; } StringBuffer text = new StringBuffer(); name = name.toLowerCase(); List itemValues = itemlist(name); if (itemValues == null) { return null; } Iterator values = itemValues.iterator(); boolean firstPart = true; while (values.hasNext()) { Object itemValue = values.next(); if (itemValue instanceof String) { String value = (String) itemValue; if (value != null) { if (firstPart) { firstPart = false; } else { text.append(" "); } text.append(value); } } } // Optionally encode String finalText = text.toString(); if (encode != null && !encode.equals("none")) { try { finalText = multiencode(encode, finalText); } catch (FormattingException e) { addwarning("Unable to highlight item '" + name + "' bc. of formating exception '" + e.getMessage() + "'."); } } return finalText; } /** * returns the metavalue as single text, concatenating eventual list elements and doing encoding * @param name * @return metavalue as text, null if item is not found or metavalue is null or metavalues are no Strings * @throws WGAPIException */ private String metaTextValue(String name, String encode) throws WGAPIException { if (name == null) { return null; } StringBuffer text = new StringBuffer(); name = name.toLowerCase(); List metaValues = metalist(name); if (metaValues == null) { return null; } Iterator values = metaValues.iterator(); boolean firstPart = true; while (values.hasNext()) { Object metaValue = values.next(); if (metaValue instanceof String) { String value = (String) metaValue; if (value != null) { if (firstPart == true) { firstPart = false; } else { text.append(" "); } text.append(value); } } } // Optionally encode String finalText = text.toString(); if (encode != null && !encode.equals("none")) { try { finalText = multiencode(encode, finalText); } catch (FormattingException e) { addwarning("Unable to highlight meta '" + name + "' bc. of formating exception '" + e.getMessage() + "'."); } } return finalText; } @SuppressWarnings("unchecked") public Iterable<Object> toIterable(Object value) throws WGException { if (value == null) { return new ArrayList<Object>(); } if (value instanceof Iterable<?>) { return (Iterable<Object>) value; } if (value instanceof Object[]) { List<Object> list = new ArrayList<Object>(); list.addAll(Arrays.asList((Object[]) value)); return list; } if (value instanceof ListVarContainer) { return ((ListVarContainer) value).getList(); } if (value instanceof java.util.Collection) { return new ArrayList<Object>((java.util.Collection<?>) value); } TMLScript tmlScript = WGA.get(this).tmlscript(); if (tmlScript.isNativeObject(value)) { // Legacy functionality for deserializing native XML int scriptType = ExpressionEngineFactory.getTMLScriptEngine().determineTMLScriptType(value); if (scriptType != RhinoExpressionEngine.TYPE_NOTMLSCRIPT) { if (scriptType == RhinoExpressionEngine.TYPE_XMLLIST) { return (List<Object>) ExpressionEngineFactory.getTMLScriptEngine().convertXMLListToList(value); } } // Modern functionality using descriptify try { return tmlScript.descriptify(value, Iterable.class); } catch (WGException e) { addwarning("Cannot use native TMLScript object as iterable: " + value.getClass().getName()); } } List<Object> list = new ArrayList<Object>(); list.add(value); return list; } @SuppressWarnings("unchecked") public static List<Object> toList(Object value) { if (value == null) { return new ArrayList<Object>(); } else if (value instanceof Object[]) { List<Object> list = new ArrayList<Object>(); list.addAll(Arrays.asList((Object[]) value)); return list; } else if (value instanceof List<?>) { return (List<Object>) value; } else if (value instanceof ListVarContainer) { return ((ListVarContainer) value).getList(); } else if (value instanceof java.util.Collection) { return new ArrayList<Object>((java.util.Collection<?>) value); } else if (ExpressionEngineFactory.getTMLScriptEngine() .determineTMLScriptType(value) == RhinoExpressionEngine.TYPE_XMLLIST) { return (List<Object>) ExpressionEngineFactory.getTMLScriptEngine().convertXMLListToList(value); } else { List<Object> list = new ArrayList<Object>(); list.add(value); return list; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#metalist(java.lang.String, java.lang.String) */ @Override public List metalist(String type, String name) throws WGAPIException { return toList(retrieveMeta(type, name)); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#metalist(java.lang.String) */ @Override public List metalist(String name) throws WGAPIException { return metalist("content", name); } private Object getMappedMetaValue(String name) { String expression = getMetaMappingExpression(name); if (expression != null) { ExpressionEngine engine = ExpressionEngineFactory.getEngine( this.content().getDatabase().getAttribute(WGACore.DBATTRIB_EXPRESSION_DEFAULT).toString()); ExpressionResult result = engine.evaluateExpression(expression, this, ExpressionEngine.TYPE_EXPRESSION, null); return result.getResult(); } else { return null; } } private String getMetaMappingExpression(String name) { @SuppressWarnings("unchecked") Map<String, String> mappings = (Map<String, String>) this.document.getDatabase() .getAttribute(WGACore.DBATTRIB_META_MAPPINGS); return mappings.get(name.toLowerCase()); } protected Object getMappedItemValue(String name) { String expression = getItemMappingExpression(name); if (expression != null) { ExpressionEngine engine = ExpressionEngineFactory.getEngine( this.content().getDatabase().getAttribute(WGACore.DBATTRIB_EXPRESSION_DEFAULT).toString()); ExpressionResult result = engine.evaluateExpression(expression, this, ExpressionEngine.TYPE_EXPRESSION, null); return result.getResult(); } else { return null; } } private String getItemMappingExpression(String name) { @SuppressWarnings("unchecked") Map<String, String> mappings = (Map<String, String>) this.getdocument().getDatabase() .getAttribute(WGACore.DBATTRIB_ITEM_MAPPINGS); name = convertVarName(name); return mappings.get(name); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setSessionVar(java.lang.String, java.lang.Object, boolean, boolean) */ public void setSessionVar(String name, Object value, boolean allowSerialization, boolean keepList) { name = convertVarName(name); if (value instanceof List && keepList) { value = new ListVarContainer((List) value); } boolean makeTransient = false; if (!allowSerialization || (getwgacore().getVariousServerOptionReader() .readOptionValueOrDefault(WGACore.SERVEROPTION_SERVER_TESTSESSIONVARSERIALIZABLE) .equals(Boolean.TRUE) && !WGUtils.isSerializable(value))) { makeTransient = true; } TransientObjectWrapper wrapper = null; wrapper = _environment.getSessionVars().get(name); if (wrapper != null && wrapper.isTransient() == makeTransient) { wrapper.set(value); } else { wrapper = TransientObjectWrapper.create(value, makeTransient); _environment.getSessionVars().put(name, wrapper); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setsessionvar(java.lang.String, java.lang.Object, boolean) */ @Override public void setsessionvar(String name, Object value, boolean allowSerialisation) { setSessionVar(name, value, allowSerialisation, true); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setsessionvar(java.lang.String, java.lang.Object) */ @Override public void setsessionvar(String name, Object value) { setSessionVar(name, value, true, true); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#removesessionvar(java.lang.String) */ @Override public void removesessionvar(String name) { name = convertVarName(name); _environment.getSessionVars().remove(name); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#content() */ @Override public WGContent content() { return getcontent(); } @CodeCompletion public WGContent getcontent() { if (this.document instanceof WGContent) { return (WGContent) this.document; } else { return null; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#context(java.lang.String, boolean) */ @Override public TMLContext context(String expression, boolean returnContextOnError) { try { TMLContextExpression expr = new TMLContextExpression(expression, this, db().getDefaultLanguage()); return expr.processExpression(this, returnContextOnError); } catch (WGAPIException e) { this.setLastError("Unable to change context to (" + expression + ") bc. of exception: " + e.getClass().getName() + " message: " + e.getMessage()); return (returnContextOnError ? this : null); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#context(java.lang.String) */ @Override public TMLContext context(String expression) { return context(expression, true); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#meta(java.lang.String, java.lang.String) */ @Override public Object meta(String type, String name) throws WGAPIException { return flattenList(retrieveMeta(type, name), !getDesignContext().getVersionCompliance().isAtLeast(7, 2)); } private Object retrieveMeta(String type, String originalName) throws WGAPIException { try { this.setLastError(null); type = (type != null ? type.toLowerCase().trim() : "content"); String name = originalName.toLowerCase().trim(); if (type.equals("content")) { return getContentMetaData(name); } else if (type.equals("profile")) { if (this.getprofile() != null) { return this.getprofile().metalist(name); } else { this.addwarning("Current user has no profile", false); return ""; } } else if (type.equals("database") || type.equals("db")) { return getDatabaseMetaData(name, originalName); } else if (type.equals("session")) { return getSessionMetaData(name); } else if (type.startsWith("domain")) { return getDomainMetaData(type, name); } else if (type.equals("request")) { return getRequestMetaData(name); } else if (type.equals("response")) { return getResponseMetaData(name); } else if (type.equals("taginfo")) { this.setLastError("Taginfos not reachable via this.meta. Use this.taginfo instead!"); return null; } else { return null; } } catch (WGAPIException e) { throw e; } catch (WGException e) { throw new WGAPIException(e); } } private Object getDomainMetaData(String type, String name) { String domainName = (String) db().getAttribute(WGACore.DBATTRIB_DOMAIN); int colonPos = type.indexOf(":"); if (colonPos != -1) { domainName = type.substring(colonPos + 1).trim(); } if (name.equalsIgnoreCase("name")) { return domainName; } else if (name.equalsIgnoreCase("username")) { DBLoginInfo loginInfo = WGACore.getSessionLogins(gethttpsession()).get(domainName); if (loginInfo != null) { return loginInfo.getUserName(); } else { return WGDatabase.ANONYMOUS_USER; } } else if (name.equalsIgnoreCase("defaultmanager")) { WGADomain dc = getwgacore().getDomains(domainName); if (dc == null) { addwarning("No configuration found for domain: " + domainName); return null; } return dc.getConfig().getDefaultManager(); } else if (name.equalsIgnoreCase("authentication") || name.equalsIgnoreCase("auth")) { WGADomain dc = getwgacore().getDomains(domainName); if (dc == null) { addwarning("No configuration found for domain: " + domainName); return null; } AuthenticationModule authModule = dc.getAuthModule(); if (authModule != null) { return authModule.getAuthenticationSource(); } else { return null; } } else if (name.equalsIgnoreCase("databases")) { return getwgacore().getDatabasesForDomain(domainName); } else { this.addwarning("Unknown domain metadata name: " + name, true); return ""; } } private Object getRequestMetaData(String name) throws WGException { WGA wga = WGA.get(this); try { if (name.equals("url")) { return wga.call().getURL(); } else if (name.equals("wgaurl")) { return wga.urlBuilder(wga.server().getBaseURL()).build(false); } else if (name.equals("absolutewgaurl")) { return wga.server().getBaseURL(); } else if (name.equals("query_string")) { return wga.call().getQueryString(); } else if (name.equals("http_referer")) { return wga.call().getReferrer(); } else if (name.equals("http_user_agent")) { return wga.call().getUserAgent(); } else if (name.equals("http_host") || name.equals("server_name")) { return wga.call().getJavaRequest().getServerName(); } else if (name.equals("path_info")) { return wga.call().getJavaRequest().getPathInfo(); } else if (name.equals("path_info_decoded")) { return wga.call().getJavaRequest().getPathTranslated(); } else if (name.equals("remote_addr")) { return wga.call().getClient(); } else if (name.equals("remote_host")) { return wga.call().getJavaRequest().getRemoteHost(); } else if (name.equals("remote_user")) { return wga.call().getJavaRequest().getRemoteUser(); } else if (name.equals("request_method")) { return wga.call().getRequestMethod(); } else if (name.equals("server_protocol")) { return wga.call().getJavaRequest().getProtocol(); } else if (name.equals("server_port")) { return wga.call().getPort(); } else if (name.equals("mainmedium")) { return wga.call().getMediaKey(); } else if (name.equals("ajax")) { return wga.call().isAjax(); } else { return null; } } catch (UnavailableResourceException e) { this.setLastError( "Cannot retrieve request metadata because this script does not run inside a WebTML request"); return null; } } private Object getResponseMetaData(String name) { if (!getEnvironment().isPageContextAvailable()) { this.setLastError( "Cannot retrieve response metadata because this script does not run inside a WebTML page"); return null; } if (name.equals("character_encoding")) { return this.getresponse().getCharacterEncoding(); } else { return null; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getprofile() */ @Override public TMLUserProfile getprofile() { return _environment.getUserProfile(getdocument().getDatabase()); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getportlet() */ @Override public TMLPortlet getportlet() throws WGAPIException { // No portlets without request if (_environment.getRequest() == null) { return null; } String nameSpace = (String) option(Base.OPTION_PORTLET_NAMESPACE); return getportletbykey(nameSpace); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#portletbypath(java.lang.String) */ @Override public TMLPortlet portletbypath(String path) throws WGException { List<String> elements = WGUtils.deserializeCollection(path, "/", true); TMLPortlet p = getportlet(); if (p == null) { setLastError("Cannot perform portletByPath(). No portlet in environment."); return null; } boolean firstElement = true; for (String elem : elements) { if (elem.equals("")) { if (firstElement) { // A starting slash means start from root p = p.getroot(); } } else if (elem.equals("..")) { p = p.getparentportlet(); } else if (elem.startsWith("parent:")) { String parentName = elem.substring(7).trim(); TMLPortlet parent = p; while (parent != null && !parentName.equals(parent)) { parent = parent.getparentportlet(); if (parent.isroot()) { parent = null; } } p = parent; } else if (elem.startsWith("name:")) { String name = elem.substring(5); p = p.getportletforname(name); } else if (elem.startsWith("key:")) { String key = elem.substring(4); p = p.getportlet(key); } else { p = p.getportletforname(elem); } if (p == null) { setLastError("Portlet path '" + path + "' unresolvable at element '" + elem + "'"); return null; } firstElement = false; } return p; } public TMLPortlet getportletbykey(String nameSpace) throws WGAPIException { TMLUserProfile profile = this.getmaincontext().getprofile(); if (profile == null || !profile.getprofile().getDatabase().isSessionOpen()) { return null; } WGPortletRegistry portletRegistry = getPortletRegistry(); if (portletRegistry == null) { return null; } WGPortlet portlet; String appDb = portletRegistry.getApplicationId(getmaincontext().db()); if (nameSpace != null) { portlet = portletRegistry.getPortlet(appDb, nameSpace); } else { portlet = portletRegistry.getOrCreateRootPortlet(appDb); } if (portlet != null) { return new TMLPortlet(this, profile, portlet); } else { return null; } } public WGPortletRegistry getPortletRegistry() throws WGAPIException { WGPortletRegistry pReg = null; if (_environment.getRequest() != null) { pReg = (WGPortletRegistry) _environment.getRequest() .getAttribute(WGACore.ATTRIB_TRANSIENTPORTLETREGISTRY); } if (pReg == null) { pReg = getmaincontext().getprofile().getprofile().getPortletRegistry(); } return pReg; } public TMLPortletStateStorage getPortletStateStorage() { return (TMLPortletStateStorage) getrequest().getAttribute(WGACore.ATTRIB_PORTLETSTATESTORAGE); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#meta(java.lang.String) */ @Override public Object meta(String name) throws WGAPIException { return this.meta("content", name); } private Object getContentMetaData(String name) throws WGException { WGContent content = this.content(); if (content == null) { return this.getdocument().getMetaData(name); } Object mappingresult = this.getMappedMetaValue(name); if (mappingresult != null) { return mappingresult; } if (name.equals("created")) { return content.getCreated(); } else if (name.equals("modified")) { return content.getLastModified(); } else if (name.equals("pagecreated")) { return content.getStructEntry().getCreated(); } else if (name.equals("url")) { return contenturl(); } else if (name.equals("titlepath")) { if (content.getStructEntry() != null) return content.getStructEntry().getTitlePath(); else return ""; } else if (name.equals("pagetitle")) { return content.getStructEntry().getTitle(); } else if (name.equals("uniquename") || name.equals("name") || name.equals("docname")) { return content.getUniqueName(); } else if (name.equals("pageuniquename") || name.equals("pagename") || name.equals("pagedocname")) { if (content.getStructEntry() != null) return content.getStructEntry().getUniqueName(); else return null; } else if (name.equals("position")) { if (content.getStructEntry() != null) { return content.getStructEntry().getPosition(); } else { return 0; } } else if (name.equals("pagesequence")) { if (content.getStructEntry() != null) { return content.getStructEntry().getPageSequence(); } else return 0; } else if (name.equals("key")) { return content.getContentKey(true).toString(); } else if (name.equals("area")) { if (!content.isDummy()) { return content.getStructEntry().getArea().getName(); } else { return ""; } } else if (name.equals("level")) { if (!content.isDummy()) { WGContentNavigator nav = new WGContentNavigator(null, new WebTMLLanguageChooser(db(), this)); return nav.getContentLevel(content); } else { return 0; } } else if (name.equals("index")) { if (!content.isDummy()) { WGContentNavigator nav = new WGContentNavigator(null, new WebTMLLanguageChooser(db(), this)); return nav.getSiblingsIndex(content); } else { return 0; } } else if (name.equals("navindex")) { if (!content.isDummy()) { WGContentNavigator nav = new WGContentNavigator(WGContent.DISPLAYTYPE_NAVIGATOR, new WebTMLLanguageChooser(db(), this)); return nav.getSiblingsIndex(content); } else { return 0; } } else if (name.equals("language")) { return content.getLanguage().getName(); } else if (name.equals("languagetitle")) { return content.getLanguage().getTitle(); } else if (name.equals("attachments")) { return content.getFileNames(); } else if (name.equals("doctype") || name.equals("contenttype")) { if (content.hasCompleteRelationships()) { return content.getStructEntry().getContentType().getName(); } else { return null; } } else if (name.equals("contenttypetitle")) { if (content.hasCompleteRelationships()) { return content.getStructEntry().getContentType().getNameForLanguage(getpreferredlanguage()); } else { return ""; } } else if (name.equals("contenttypedescription")) { if (content.hasCompleteRelationships()) { return content.getStructEntry().getContentType().getDescriptionForLanguage(getpreferredlanguage()); } else { return ""; } } else if (name.equals("siblings")) { if (!content.isDummy()) { WGContentNavigator nav = new WGContentNavigator(null, new WebTMLLanguageChooser(db(), this)); return new Integer(nav.getSiblingsCount(content)); } else { return 0; } } else if (name.equals("workflow")) { if (content.getStatus().equals(WGContent.STATUS_DRAFT) || content.getStatus().equals(WGContent.STATUS_REVIEW)) { WGWorkflow wf = content.getWorkflow(); if (wf instanceof WGNamedWorkflow) { return ((WGNamedWorkflow) wf).getWorkflowName(); } } if (content.getStructEntry() != null) { return content.getStructEntry().getWorkflowName(); } return null; } else if (name.equals("status")) { return content.getStatus(); } else if (name.equals("structtitle")) { if (content.getStructEntry() != null) { return content.getStructEntry().getTitle(); } else { return ""; } } else if (name.equals("structkey") || name.equals("pagekey")) { return content.getContentKey().getStructKey(); } else if (name.equals("itemnames")) { return content.getItemNames(); } else if (name.equals("searchscore")) { return new Float(content.getSearchScore()); } else if (name.equals("searchexplanation")) { return content.getSearchExplanation(); } else if (name.equals("searchdoctype")) { SearchDetails sd = content.getSearchDetails(); if (sd instanceof LuceneSearchDetails) { return ((LuceneSearchDetails) sd).getDoctype(); } else { return null; } } else if (name.equals("searchfilename")) { SearchDetails sd = content.getSearchDetails(); if (sd instanceof LuceneSearchDetails) { return ((LuceneSearchDetails) sd).getFilename(); } else { return null; } } else if (name.equals("positionpath")) { if (content.getStructEntry() != null) { return content.getStructEntry().getPositionPath(); } else { return ""; } } else if (name.equals("pagepublished")) { if (content.getStructEntry() != null) { return content.getStructEntry().getPublished().get(content.getLanguage().getName()); } else { return null; } } else if (name.equals("email")) { return content.getAuthorEMail(); } else { Object result = null; String upperName = name.toUpperCase(); boolean isNoValidMeta = true; if (content.getMetaInfo(upperName) != null) { result = content.getMetaData(upperName); isNoValidMeta = false; } else { WGStructEntry structEntry = content.getStructEntry(); if (structEntry != null) { if (structEntry.getMetaInfo(upperName) != null) { result = structEntry.getMetaData(upperName); isNoValidMeta = false; } else { WGContentType docType = structEntry.getContentType(); if (docType != null) { if (docType.getMetaInfo(upperName) != null) { result = docType.getMetaData(upperName); isNoValidMeta = false; } } } } } if (isNoValidMeta) { return ""; } return result; } } private Object getDatabaseMetaData(String name, String originalName) throws WGAPIException { if (name.equals("title")) { return this.getdocument().getDatabase().getTitle(); } else if (name.equals("path")) { return this.getdocument().getDatabase().getPath(); } else if (name.equals("type")) { return this.getdocument().getDatabase().getType(); } else if (name.equals("dbkey")) { return this.getdocument().getDatabase().getAttribute(WGACore.DBATTRIB_DBKEY); } else if (name.startsWith("user")) { return getDatabaseUserMetaData(db().getSessionContext().getUserAccess(), name, originalName); } else if (name.startsWith("original_user")) { WGUserAccess userAccess = getoriginaluserdata(); if (userAccess != null) { return getDatabaseUserMetaData(userAccess, name.substring(9), originalName.substring(9)); } else { return null; } } else if (name.equals("domain")) { return (String) this.getdocument().getDatabase().getAttribute(WGACore.DBATTRIB_DOMAIN); } else if (name.equals("filecontainers")) { return getDesignDocNames(this.getdocument().getDatabase().getFileContainers()); } else if (name.equals("contenttypes")) { return getDesignDocNames(this.getdocument().getDatabase().getContentTypes()); } else if (name.equals("cssjsmodules")) { return getDesignDocNames(this.getdocument().getDatabase().getCSSJSModules()); } else if (name.equals("tmlmodules")) { return getDesignDocNames(this.getdocument().getDatabase().getTMLModules()); } else if (name.equals("areas")) { return getDesignDocNames(this.getdocument().getDatabase().getAreas().values()); } else if (name.equals("languages")) { return getDesignDocNames(this.getdocument().getDatabase().getLanguages().values()); } else if (name.equals("defaultlanguage")) { return getdocument().getDatabase().getDefaultLanguage(); } else if (name.equals("servername")) { return getdocument().getDatabase().getServerName(); } else if (name.equals("lucene")) { return getwgacore().getLuceneManager().indexIsEnabled(db().getDbReference()); } else { this.addwarning("Unknown metadata name: " + name, true); return ""; } } private Object getDatabaseUserMetaData(WGUserAccess userAccess, String name, String originalName) throws WGAPIException { // Look if we have detailed user information WGUserDetails userDetails = null; if (userAccess instanceof WGUserDetails) { userDetails = (WGUserDetails) userAccess; } if (name.equals("username")) { return userAccess.getPrimaryName(); } else if (name.equals("useraccess")) { return new Integer(userAccess.getAccessLevel()); } else if (name.equals("userlabels")) { if (userDetails != null) { return new ArrayList(userDetails.getLabeledNames().keySet()); } else { return Collections.emptyList(); } } else if (name.startsWith("userlabel_") || name.startsWith("useralias_")) { if (userDetails != null) { int sublinePos = name.indexOf("_"); String label = originalName.substring(sublinePos + 1); return userDetails.getLabeledNames().get(label); } else { return null; } } else if (name.equals("useraliases")) { if (userDetails != null) { return userDetails.getAliases(); } else { return null; } } else if (name.equals("userroles")) { if (userDetails != null) { return userDetails.getRoles(); } else { return null; } } else if (name.equals("usergroups")) { if (userDetails != null) { return userDetails.getGroups(); } else { return null; } } else if (name.equals("useremail")) { if (userDetails != null) { return userDetails.getEMailAddress(); } else { return null; } } else if (name.equals("usermaymovestructs")) { return new Boolean(userAccess.mayMoveStructEntries()); } else if (name.equals("usermaydeletedocs")) { return new Boolean(userAccess.mayDeleteDocuments()); } else { this.addwarning("Unknown metadata name: " + name, true); return ""; } } private Object getDesignDocNames(Collection containers) throws WGAPIException { Iterator designDocs = containers.iterator(); WGDesignDocument designDoc; List designDocNames = new ArrayList(); while (designDocs.hasNext()) { designDoc = (WGDesignDocument) designDocs.next(); designDocNames.add(designDoc.getName()); } return designDocNames; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#taginfo(java.lang.String) */ @Override public TagInfo tag(String tagId) throws WGAPIException { BaseTagStatus tag = _designContext.getTag(); if (tag == null) getlog().error("taginfo: no TML environment"); if (tag != null && tagId != null) { tag = tag.getTagStatusById(tagId); if (tag == null) { String msg = "taginfo: Could not find tag with id = " + tagId; getlog().error(msg); this.setLastError(msg); } } return new TagInfo(tag); } public TagInfo tag() throws WGAPIException { return tag(null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#taginfo(java.lang.String, java.lang.String) */ @Override @Deprecated public Object taginfo(String tagId, String name) throws WGAPIException { BaseTagStatus tag = _designContext.getTag(); if (tag == null) { return null; } if (tagId == null) { this.setLastError("No WebTML tag environment available"); return null; } BaseTagStatus refTag = tag.getTagStatusById(tagId); if (refTag != null) { Object result = refTag.getTagInfo(String.valueOf(name).toLowerCase()); if (result == null) { this.setLastError("Tag " + tagId + " did not provide Info " + name); } return result; } else { addwarning("Could not find tag for tagid " + tagId, false); this.setLastError("Could not find tag for tagid " + tagId); return null; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getlasterror() */ @Override public String getlasterror() { return lastError; } public void setLastError(String lastError) { this.lastError = lastError; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isselected() */ @Override public boolean isselected() throws WGAPIException { TMLContext mainContext = getmaincontext(); return isselected(mainContext); } @Override public boolean isselected(Context mainContext) throws WGAPIException { boolean isSelected = false; WGContent pageContent = mainContext.content(); if (pageContent.getDatabase() != this.document.getDatabase()) { return false; } WGContentNavigator navigator = new WGContentNavigator(this.role, new WebTMLLanguageChooser(db(), this)); navigator.setOnlyPublished(!isbrowserinterface()); while (pageContent != null) { if (pageContent.getStructKey().equals(this.content().getStructKey())) { isSelected = true; break; } if (pageContent.hasCompleteRelationships() && !pageContent.getStructEntry().isRoot()) { pageContent = navigator.getParentContent(pageContent); } else { pageContent = null; } } return isSelected; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#haschildren() */ @Override public boolean haschildren() throws WGAPIException { WGContentNavigator navigator = new WGContentNavigator(this.role, new WebTMLLanguageChooser(db(), this)); return navigator.hasContentChildren(getcontent()); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#hassiblings() */ @Override public boolean hassiblings() throws WGAPIException { WGContentNavigator navigator = new WGContentNavigator(this.role, new WebTMLLanguageChooser(db(), this)); return navigator.getSiblingsCount(getcontent()) != 0; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isroot() */ @Override public boolean isroot() throws WGAPIException { return getcontent().isDummy() || getcontent().getStructEntry().isRoot(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#ismaindocument() */ @Override public boolean ismaindocument() throws WGAPIException { return (document == getmaincontext().content()); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isbrowserinterface() */ @Override public boolean isbrowserinterface() { WGA wga = WGA.get(this); if (wga.call().isAvailable()) { try { return WGPDispatcher.isBrowserInterface(wga.call().getJavaRequest().getSession()); } catch (WGException e) { getlog().error("Exception determining browser interface", e); return false; } } else { return false; } } /* (non-Javadoc) * @see de.innovationgate.wga.server.api.tml.Context#contenturl() */ @Override public String contenturl() throws WGException { return contenturl(null, null, false); } /* (non-Javadoc) * @see de.innovationgate.wga.server.api.tml.Context#contenturl(java.lang.String, java.lang.String) */ @Override public String contenturl(String mediaKey) throws WGException { return contenturl(mediaKey, null, false); } /* (non-Javadoc) * @see de.innovationgate.wga.server.api.tml.Context#contenturl(java.lang.String, java.lang.String) */ @Override public String contenturl(String mediaKey, String layoutKey) throws WGException { return contenturl(mediaKey, layoutKey, false); } /* (non-Javadoc) * @see de.innovationgate.wga.server.api.tml.Context#contenturl(java.lang.String, java.lang.String, boolean) */ @Override public String contenturl(String mediaKey, String layoutKey, boolean ignoreVirtualLink) throws WGException { return getURLBuilder().buildContentURL(toUnlockedVersion(), mediaKey, layoutKey, ignoreVirtualLink); } public String contentdataurl(String mediaKey, String layoutKey) throws ServletException, IOException, WGException { return contentdataurl(mediaKey, layoutKey, false, null); } public String contentdataurl(String mediaKey, String layoutKey, String queryString) throws ServletException, IOException, WGException { return contentdataurl(mediaKey, layoutKey, false, queryString); } public String contentdataurl(String mediaKey, String layoutKey, boolean ignoreVirtualLink, String queryString) throws ServletException, IOException, WGException { BaseTagStatus tag = _designContext.getTag(); if (tag == null) { return null; } TMLContext unlockedCx = toUnlockedVersion(); // retrieve standard contenturl String url = contenturl(mediaKey, layoutKey, ignoreVirtualLink); // cut off WGPath url = url.substring(url.indexOf(_environment.getPublisherURL()) + _environment.getPublisherURL().length()); // append query string if (queryString != null) { url = url + "?" + queryString; } MediaKey key = getwgacore().getMediaKey(mediaKey); String contentType = key.getMimeType(); /** this works on WAS - on tomcat the result is an endless loop // create wrapper for request and response RenderServletRequestWrapper req = new RenderServletRequestWrapper(this.getrequest(), url); RenderServletResponseWrapper res = new RenderServletResponseWrapper(this.getresponse()); **/ RenderServletRequest req = new RenderServletRequest(unlockedCx.getrequest(), url); RenderServletResponse res = new RenderServletResponse(unlockedCx.getresponse()); // call include this.getrequest().getRequestDispatcher(url).include(req, res); // process response if (res.isBinary()) { byte data[] = res.getBinaryData(); return createDataURL(data, contentType); } else { String data = res.getStringData(); return createDataURL(data, contentType); } } public int getDummy() { return 1; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#layouturl(java.lang.String, java.lang.String, java.lang.String) */ @CodeCompletion public String layouturl(String dbKey, String mediaKey, String layoutKey) throws WGException { return getURLBuilder().buildLayoutURL(toUnlockedVersion(), resolveDBKey(dbKey), mediaKey, layoutKey); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#layouturl(java.lang.String, java.lang.String) */ @CodeCompletion public String layouturl(String mediaKey, String layoutKey) throws WGException { return layouturl(null, mediaKey, layoutKey); } public void setrole(String role) { this.role = role; } public String getrole() { return this.role; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#addwarning(java.lang.String, boolean) */ @Override public void addwarning(String msg, boolean severe) { _designContext.addWarning(this, msg, severe, null); } @Override public void addwarning(String msg, boolean severe, Throwable cause) { _designContext.addWarning(this, msg, severe, cause); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#addwarning(java.lang.String) */ @Override public void addwarning(String msg) { addwarning(msg, false); } private Object getSessionMetaData(String name) { if (!getEnvironment().isPageContextAvailable()) { this.setLastError( "Cannot retrieve session metadata because this script does not run inside a WebTML page"); return null; } HttpSession session = gethttpsession(); if (name.equals("start")) { return new Date(session.getCreationTime()); } else if (name.equals("lastaccess")) { return new Date(session.getLastAccessedTime()); } else if (name.equals("id")) { return session.getId(); } else if (name.equals("language")) { return getpreferredlanguage(); } else { return null; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isnewsession() */ @Override public boolean isnewsession() { if (!getEnvironment().isPageContextAvailable()) { return false; } return gethttpsession().isNew(); } public javax.servlet.http.Cookie[] getcookies() { if (!_environment.isPageContextAvailable()) { return null; } return getrequest().getCookies(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getrequest() */ @Override @CodeCompletion public javax.servlet.http.HttpServletRequest getrequest() { return _environment.getRequest(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#istrue(java.lang.String) */ @Override public boolean istrue(String varname) throws WGAPIException { Object value = varname.equals(varname.toUpperCase()) ? this.meta(varname) : this.item(varname); // Enhanced "true", using JavaScript rules to determine true/false. if (isEnhancedItemExpressions()) { if (value == null) { return false; } if (value instanceof Boolean) { return ((Boolean) value).booleanValue(); } if (value instanceof Number && (((Number) value).intValue() == 0 || ((Number) value).doubleValue() == Double.NaN)) { return false; } if (value.equals("")) { return false; } int scriptType = ExpressionEngineFactory.getTMLScriptEngine().determineTMLScriptType(value); if (scriptType == RhinoExpressionEngine.TYPE_UNDEFINED || scriptType == RhinoExpressionEngine.TYPE_NAN) { return false; } return true; } // Legacy "true", using boolean values, numbers 1 or -1 and string literals "true"/"false" else { if (value instanceof Boolean) { return ((Boolean) value).booleanValue(); } else if (value instanceof Number) { int valueNumber = ((Number) value).intValue(); if (valueNumber == 1 || valueNumber == -1) { return true; } else { return false; } } else if (value instanceof String) { return Boolean.valueOf((String) value).booleanValue(); } else { return false; } } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isdefined(java.lang.String) */ @Override public boolean isdefined(String name) throws WGAPIException { name = convertVarName(name); TMLPortlet portlet = getportlet(); Map<String, Object> vars = _environment.getPageVars(); // Portlet variables if (portlet != null && !portlet.isroot()) { String pName = portlet.getVarPrefix() + name; // Request variables if (vars.containsKey(pName)) { return true; } // Session variables if (portlet.hassessionvar(name)) { return true; } } // Local variables (since 7.2) if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { Object value = getDesignContext().retrieveLocalVar(name); if (!(value instanceof NullPlaceHolder)) { return true; } } // Request variables if (vars.containsKey(name)) { return true; } // Session variables Map<String, TransientObjectWrapper<Object>> sessionVars = _environment.getSessionVars(); if (sessionVars.containsKey(name) && sessionVars.get(name).get() != null) { return true; } // Mapped item values Object result = this.getItemMappingExpression(name); if (result != null) { return true; } // Content items return this.document.hasItem(name); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isfalse(java.lang.String) */ public boolean isfalse(String varname) throws WGAPIException { return !this.istrue(varname); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#option(java.lang.String, java.lang.Object) */ @Override public Object option(String optionName, Object defaultValue) { try { TMLOption option = _designContext.getOption(optionName); if (option == null || option.getValue() == null) { return defaultValue; } else { return option.getValue(); } } catch (WGException e) { addwarning("Error retrieving WebTML option '" + optionName + "': " + e.getMessage()); getlog().error("Error retrieving WebTML option '" + optionName + "'", e); return null; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#option(java.lang.String) */ @Override public Object option(String option) { return option(option, null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#hasoption(java.lang.String) */ @Override public boolean hasoption(String option) { return (this.option(option) != null); } public Date dateonly(Date date) { return WGUtils.dateOnly(date); } public Date timeonly(Date date) { return WGUtils.timeOnly(date); } @CodeCompletion public WGDocument getapiobject() { return this.document; } public Date stringtodate(String text) { if (text == null) { return null; } if (text.indexOf(":") == -1) { text += " 0:00"; } SimpleDateFormat dateFormat = new SimpleDateFormat(); dateFormat.setLenient(true); return dateFormat.parse(text, new ParsePosition(0)); } @CodeCompletion public List createlist() { return WGA.get(this).createList(); } @CodeCompletion public List createlist(Object[] objects) { if (objects != null) { return WGA.get(this).createList(objects); } else { return createlist(); } } @CodeCompletion public List createlist(String listString, String delimiter) { return WGA.get(this).createList(listString, delimiter); } public int createuserprofile(String name, String password) throws WGAPIException { return this.createuserprofile((String) this.content().getDatabase().getAttribute(WGACore.DBATTRIB_DOMAIN), name, password); } public int createuserprofile(String domain, String name, String password) throws WGAPIException { return createuserprofile(domain, name, password, true); } public int createuserprofile(String domain, String name, String password, boolean forCurrentUser) throws WGAPIException { if (getEnvironment().getRequest() == null) { return TMLUserProfile.RC_METHOD_UNAVAILABLE; } // Get pers db. Ensure that there is one if (domain == null || domain.equals("")) { return TMLUserProfile.RC_NO_DOMAIN; } HttpSession session = getEnvironment().getRequest().getSession(); if (session == null) { return TMLUserProfile.RC_NO_SESSION; } WGDatabase persDB = getwgacore().openPersonalisationDB(domain); if (persDB == null) { return TMLUserProfile.RC_NOT_PERSONALIZED; } // ensure persdb is in correct mode (custom) Integer persMode = Integer.valueOf((String) getwgacore() .readPublisherOptionOrDefault(getDesignContext().getDesignDB(), WGACore.DBATTRIB_PERSMODE)); if (persMode.intValue() != Constants.PERSMODE_CUSTOM) { return TMLUserProfile.RC_WRONG_PERSMODE; } // Ensure, there is no profile yet with this name WGUserProfile profile = persDB.getUserProfile(name); if (profile != null) { return TMLUserProfile.RC_PROFILE_EXISTS; } // Try to create the profile try { profile = persDB.createUserProfile(name, Constants.PERSMODE_CUSTOM); } catch (WGException e) { this.addwarning("Exception creating user profile: " + e.getMessage(), true); } if (profile == null) { return TMLUserProfile.RC_NOT_CREATABLE; } TMLUserProfile.prepareNewProfile(profile, getrequest()); // Set password eventually if (password != null) { profile.setMetaData(WGUserProfile.META_PASSWORD, password); } try { profile.save(); } catch (WGAPIException e) { this.addwarning("Unable to create user profile: " + e.getMessage(), true); return TMLUserProfile.RC_NOT_CREATABLE; } // Attach to session if (forCurrentUser) { attachProfileToUser(domain, profile); } return TMLUserProfile.RC_OK; } public int assignuserprofile(String name, String password) throws WGAPIException { return this.assignuserprofile((String) this.content().getDatabase().getAttribute(WGACore.DBATTRIB_DOMAIN), name, password); } public int assignuserprofile(String domain, String name, String password) throws WGAPIException { if (getEnvironment().getRequest() == null) { return TMLUserProfile.RC_METHOD_UNAVAILABLE; } password = (password == null ? "" : password); // Get pers db. Ensure that there is one if (domain == null || domain.equals("")) { return TMLUserProfile.RC_NO_DOMAIN; } HttpSession session = getEnvironment().getRequest().getSession(); if (session == null) { return TMLUserProfile.RC_NO_SESSION; } WGDatabase persDB = getwgacore().openPersonalisationDB(domain); if (persDB == null) { return TMLUserProfile.RC_NOT_PERSONALIZED; } // ensure database is in correct mode (custom) Integer persMode = Integer.valueOf((String) getwgacore() .readPublisherOptionOrDefault(getDesignContext().getDesignDB(), WGACore.DBATTRIB_PERSMODE)); if (persMode.intValue() != Constants.PERSMODE_CUSTOM) { return TMLUserProfile.RC_WRONG_PERSMODE; } // Try to fetch profile WGUserProfile profile = persDB.getUserProfile(name); if (profile == null) { return TMLUserProfile.RC_NO_PROFILE; } // Test password if (!password.equals(profile.getPassword())) { return TMLUserProfile.RC_WRONG_PASSWORD; } // Attach to session & request and register hit attachProfileToUser(domain, profile); if (!isbrowserinterface()) { getwgacore().getPersManager().registerHit(profile, this.content().getDatabase(), this.content()); } return TMLUserProfile.RC_OK; } private void attachProfileToUser(String domain, WGUserProfile profile) throws WGAPIException { if (!getEnvironment().isPageContextAvailable()) { addwarning("Cannot use this method in this TMLScript runtime", false); return; } if (profile != null) { gethttpsession().setAttribute(PersonalisationManager.SESSION_PROFILENAME + domain, profile.getName()); } else { gethttpsession().removeAttribute(PersonalisationManager.SESSION_PROFILENAME + domain); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#gettmlform() */ @Override public TMLForm gettmlform() { TMLForm form = null; // Use form predefined by environment if (_environment != null && _environment.getForm() != null) { form = _environment.getForm(); } // Use last defined form on the WebTML request if (form == null && getrequest() != null) { form = (TMLForm) getrequest().getAttribute(WGACore.ATTRIB_LASTFORM); } return form; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#tmlformbyid(java.lang.String) */ @Override public TMLForm tmlformbyid(String id) { TMLForm form = (TMLForm) getTransientForms().get(id); if (form != null) { return form; } form = (TMLForm) getPersistentForms().get(id); if (form != null) { return form; } return null; } private Map getTransientForms() { return _environment.getTransientForms(); } @CodeCompletion public WGDatabase db(String key) throws WGException { return WGA.get(this).db(key); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#db() */ @Override public WGDatabase db() { return document.getDatabase(); } @CodeCompletion public WGDatabase designdb() throws WGException { WGDatabase designDB = _designContext.getDesignDB(); return _environment.openDB(designDB); } @CodeCompletion public WGHierarchicalDatabase hdb(String key) throws WGException { return WGA.get(this).hdb(key); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#hdb() */ @Override public WGHierarchicalDatabase hdb() throws WGException { return hdb(db().getDbReference()); } public int closeuserprofile(String domain) throws WGAPIException { HttpSession session = gethttpsession(); if (session == null) { return TMLUserProfile.RC_NO_SESSION; } TMLUserProfile profile = this.getprofile(); if (profile == null) { return TMLUserProfile.RC_NO_PROFILE; } Integer mode = Integer.valueOf((String) getwgacore() .readPublisherOptionOrDefault(profile.getprofile().getDatabase(), WGACore.DBATTRIB_PERSMODE)); if (mode.intValue() != Constants.PERSMODE_CUSTOM) { return TMLUserProfile.RC_WRONG_PERSMODE; } attachProfileToUser(domain, null); return TMLUserProfile.RC_OK; } public int closeuserprofile() throws WGAPIException { return this.closeuserprofile((String) this.content().getDatabase().getAttribute(WGACore.DBATTRIB_DOMAIN)); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#hasprofile() */ @Override public boolean hasprofile() { return (this.getprofile() != null); } // For binary backward compatibility to WGA 6.0 (#00002388) /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#context(de.innovationgate.webgate.api.WGContent) */ @Override @CodeCompletion public TMLContext context(WGContent content) throws WGAPIException { return getTMLContextForDocument(content); } public TMLContext context(WGDocument doc) throws WGAPIException { return getTMLContextForDocument(doc); } @CodeCompletion public SmtpMail createmail(String smtpHost, String username, String password) throws UnsupportedEncodingException { try { return WGA.get(this).createMail(smtpHost, username, password); } catch (WGException e) { throw new RuntimeException(e); } } @CodeCompletion public SmtpMail createmail() throws TMLException { try { return WGA.get(this).createMail(); } catch (UnsupportedEncodingException e) { throw new TMLException("Unsupported encoding: " + e.getMessage()); } catch (WGException e) { throw new TMLException(e.getMessage()); } } @CodeCompletion public ImageScaler createimagescaler(File imageFile) throws WGException, IOException { return WGA.get(this).createImageScaler(imageFile); } @CodeCompletion public ImageScaler createimagescaler(InputStream is) throws WGException, IOException { return WGA.get(this).createImageScaler(is); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getpath() */ @Override public String getpath() throws WGAPIException { StringBuffer path = new StringBuffer(); WGDocument doc = getdocument(); path.append("db:" + doc.getDatabase().getAttribute(WGACore.DBATTRIB_DBKEY)); switch (doc.getType()) { case WGDocument.TYPE_CONTENT: if (!getcontent().isDummy()) { path.append("/docid:" + getcontent().getContentKey().toString()); } else { path.append("<").append(getcontent().getLanguage().getName()).append(">"); } break; case WGDocument.TYPE_STRUCTENTRY: path.append("/$struct:" + ((WGStructEntry) doc).getStructKey()); break; case WGDocument.TYPE_AREA: path.append("/$area:" + ((WGArea) doc).getName()); break; case WGDocument.TYPE_CONTENTTYPE: path.append("/$contenttype:" + ((WGContentType) doc).getName()); break; case WGDocument.TYPE_LANGUAGE: path.append("/$language:" + ((WGLanguage) doc).getName()); break; case WGDocument.TYPE_TML: path.append("/$tml:" + ((WGTMLModule) doc).getName() + "," + ((WGTMLModule) doc).getMediaKey()); break; case WGDocument.TYPE_CSSJS: path.append("/$cssjs:" + ((WGCSSJSModule) doc).getName()); break; case WGDocument.TYPE_FILECONTAINER: path.append("/$filecontainer:" + ((WGFileContainer) doc).getName()); } return path.toString(); } public void registerForm(TMLForm form, boolean persist) { _environment.setForm(form); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getresponse() */ @Override @CodeCompletion public HttpServletResponse getresponse() { return (HttpServletResponse) _environment.getResponse(); } @CodeCompletion public void redirectto(String url) throws IOException { getrequest().setAttribute(WGACore.ATTRIB_REDIRECT, getresponse().encodeURL(url)); } public TMLContext getTMLContextForDocument(WGDocument doc) { return _environment.getTMLContextForDocument(this, doc); } public static String createContextKey(WGDocument doc) { return doc.getDatabase().getDbReference() + "//" + doc.getDocumentKey().toString(); } public Cookie createcookie(String name, String value) { return new Cookie(name, value); } public Cookie createCookie(String name, String value) { return new Cookie(name, value); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#getlog() */ @Override public Logger getlog() { return getEnvironment().getLog(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#removevar(java.lang.String) */ @Override public void removevar(String name) throws WGAPIException { String lcName = convertVarName(name); // Local variables (since 7.2) if (getDesignContext().getVersionCompliance().isAtLeast(7, 2)) { Object value = getDesignContext().retrieveLocalVar(lcName); if (!(value instanceof NullPlaceHolder)) { getDesignContext().removeLocalVar(lcName); return; } } _environment.getPageVars().remove(lcName); if (this.document.getDatabase().hasFeature(WGDatabase.FEATURE_STORESVARS)) { this.document.removeItem(name); } } @CodeCompletion public WGACore getwgacore() { return _environment.getCore(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#gethttpsession() */ @Override public HttpSession gethttpsession() { return _environment.getSession(); } /** * @deprecated */ public void setpreferredlanguage(String lang) { addwarning("Method TMLContext.setPreferredLanguage() is deprecated and inoperable since OpenWGA 5.1"); } /** * Returns the preferred language for the given content context * This equals calling {@link #getpreferredlanguage(WGDatabase, boolean)} with the current context database and "true" for the exhaustive parameter * @throws WGAPIException * @deprecated */ public String getpreferredlanguage() { return getpreferredlanguage(db(), true); } /** * Determines the preferred language for the given database * @param The database for whom the preferred language is determined. It is used to evaluate the available languages and to read it's language behaviour setting * @param exhaustive Set to true if the method should try to find a appropriate language even if the pref language was not yet set for the user session * @return The preferred language or null if none could be determined * @deprecated */ protected String getpreferredlanguage(WGDatabase db, boolean exhaustive) { WebTMLLanguageChooser chooser = new WebTMLLanguageChooser(db, this); try { String lang = chooser.getPreferredLanguage(db); if (lang != null) { return lang; } else { return getmaincontext().content().getLanguage().getName(); } } catch (WGAPIException e) { getlog().error("Exception retrieving preferred language for database " + db.getDbReference(), e); return null; } } public Locale getPreferredLanguageLocale() { String prefLang = getpreferredlanguage(); if (prefLang == null) { return null; } return getwgacore().languageCodeToLocale(prefLang); } @CodeCompletion public Date parsedate(String date, String format) throws ParseException, WGException { return WGA.get(this).getDateFormat(format, null).parse(date); } @CodeCompletion public Number parsenumber(String number, String format) throws ParseException, WGException { return WGA.get(this).getNumberFormat(format, null).parse(number); } @CodeCompletion public Date createdate() { return createdate(true); } @CodeCompletion public Date now() { return createdate(); } @CodeCompletion public Date createdate(boolean includeMillis) { try { return WGA.get(this).createDate(includeMillis); } catch (WGException e) { throw new RuntimeException(e); } } public Calendar createcalendar(Date date) { try { return WGA.get(this).createCalendar(date); } catch (WGException e) { throw new RuntimeException(e); } } public Calendar createcalendar() { try { return WGA.get(this).createCalendar(null); } catch (WGException e) { throw new RuntimeException(e); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setoption(java.lang.String, java.lang.Object, java.lang.String) */ @Override public void setoption(String name, Object value, String scope) { try { _designContext.setOption(name, value, scope); } catch (WGException e) { addwarning("Error setting WebTML option '" + name + "': " + e.getMessage()); getlog().error("Error setting WebTML option '" + name + "'", e); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#setoption(java.lang.String, java.lang.Object) */ @Override public void setoption(String name, Object value) { setoption(name, value, TMLOption.SCOPE_GLOBAL); } public Login createlogin(String username, String password) { return new Login(username, password); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String, java.lang.String, java.lang.String, java.util.List, boolean) */ @Override public String label(String containerName, String fileName, String key, List params, boolean usePlaceholder) { try { return WGA.get(this).design().label(containerName, fileName, key, params, usePlaceholder); } catch (WGException e) { getlog().error("Unable to open design db", e); return "(Error retrieving label)"; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String, java.lang.String, java.lang.String, java.util.List) */ @Override public String label(String containerName, String fileName, String key, List params) { return label(containerName, fileName, key, params, true); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(de.innovationgate.webgate.api.WGDatabase, java.lang.String, java.lang.String, java.lang.String, java.util.List, boolean) */ @Override public String label(WGDatabase designDB, String containerName, String fileName, String key, List<String> params, boolean usePlaceholder) throws WGException { return WGA.get(this).design(designDB).label(containerName, fileName, key, params, usePlaceholder); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(de.innovationgate.webgate.api.WGDatabase, java.lang.String, java.lang.String, java.lang.String, java.util.List) */ @Override public String label(WGDatabase designDB, String containerName, String fileName, String key, List params) throws WGException { return label(designDB, containerName, fileName, key, params, true); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String, java.lang.String, java.lang.String) */ @Override public String label(String containerName, String fileName, String key) { return label(containerName, fileName, key, null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String, java.lang.String, java.util.List) */ @Override public String label(String fileName, String key, List params) { return label(null, fileName, key, params); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String, java.lang.String) */ @Override public String label(String fileName, String key) { return label(null, fileName, key, null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String, java.util.List) */ @Override public String label(String key, List params) { return label(null, null, key, params); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#label(java.lang.String) */ @Override public String label(String key) { return label(null, null, key, null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#haslabel(java.lang.String) */ @Override public boolean haslabel(String key) { return (label(null, null, key, null, false) != null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#haslabel(java.lang.String, java.lang.String) */ @Override public boolean haslabel(String fileName, String key) { return (label(null, fileName, key, null, false) != null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#haslabel(java.lang.String, java.lang.String, java.lang.String) */ @Override public boolean haslabel(String containerName, String fileName, String key) { return (label(containerName, fileName, key, null, false) != null); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#iswebenvironment() */ @Override public boolean iswebenvironment() { return getEnvironment().isWebEnvironment(); } /** * wrapper for TestCore.assertTrue(...) * @param title assertion-title * @param category assertion-category * @param condition tmlscript-condition to test for true */ @CodeCompletion public void asserttrue(String title, String category, String condition) { this.getwgacore().getTestCore().assertTrue(title, category, condition, this); } /** * wrapper for TestCore.assertEquals(...) * @param title assertion-title * @param category assertion-category * @param obj1 Object1 for compare * @param obj2 Object2 for compare */ @CodeCompletion public boolean assertequals(String title, String category, Object obj1, Object obj2) { return this.getwgacore().getTestCore().assertEquals(title, category, obj1, obj2, this); } @CodeCompletion public boolean assertlarger(String title, String category, Number obj1, Number obj2) { return this.getwgacore().getTestCore().assertLarger(title, category, (Comparable) obj1, (Comparable) obj2, this); } @CodeCompletion public boolean assertlarger(String title, String category, Date obj1, Date obj2) { return this.getwgacore().getTestCore().assertEquals(title, category, obj1, obj2, this); } /** * wrapper for TestCore.assertNotEquals(...) * @param title assertion-title * @param category assertion-category * @param obj1 Object1 for compare * @param obj2 Object2 for compare */ @CodeCompletion public boolean assertnotequals(String title, String category, Object obj1, Object obj2) { return this.getwgacore().getTestCore().assertNotEquals(title, category, obj1, obj2, this); } /** * Compares two lists based on their contents but not on their order * @param title assertion-title * @param category assertion-category * @param l1 List 1 for compare * @param l2 List 2 for compare * @param ignoreOrder Set to true to ignore list order */ @CodeCompletion public boolean assertequallists(String title, String category, List l1, List l2) { return assertequallists(title, category, l1, l2, true); } /** * Compares two lists based on their contents * @param title assertion-title * @param category assertion-category * @param l1 List 1 for compare * @param l2 List 2 for compare * @param ignoreOrder Set to true to ignore list order */ @CodeCompletion public boolean assertequallists(String title, String category, List l1, List l2, boolean ignoreOrder) { List sorted1 = (l1 != null ? new ArrayList(l1) : Collections.emptyList()); List sorted2 = (l2 != null ? new ArrayList(l2) : Collections.emptyList()); if (ignoreOrder) { Collections.sort(sorted1); Collections.sort(sorted2); } return this.getwgacore().getTestCore().assertEquals(title, category, sorted1, sorted2, this); } /** * wrapper for TestCore.assertTrue(...) * @param id of preregistered assertion * @param condition tmlscript-condition to test for true */ @CodeCompletion public void asserttrue(String id, String condition) { this.getwgacore().getTestCore().assertTrue(id, condition, this); } /** * wrapper for TestCore.assertEquals(...) * @param id of preregistered assertion * @param obj1 Object1 for compare * @param obj2 Object2 for compare */ @CodeCompletion public void assertequals(String id, Object obj1, Object obj2) { this.getwgacore().getTestCore().assertEquals(id, obj1, obj2, this); } /** * wrapper for TestCore.registerAssertTrue() * @param id unqiue id for the assertion * @param title assertion-title * @param category assertion-category */ public void registerasserttrue(String id, String title, String category) { this.getwgacore().getTestCore().registerAssertTrue(id, title, category); } /** * wrapper for TestCore.registerAssertEquals() * @param id unqiue id for the assertion * @param title assertion-title * @param category assertion-category */ public void registerassertequals(String id, String title, String category) { this.getwgacore().getTestCore().registerAssertEquals(id, title, category); } /** * wrapper for TestCore.assertIsRegisteredOrExecuted() * @param id unique id for the assertion * @return true/false */ @CodeCompletion public boolean assertisregisteredorexecuted(String id) { return this.getwgacore().getTestCore().assertIsRegisteredOrExecuted(id); } /** * enable or disable TestCore.assertionDebugMode */ @CodeCompletion public void assertiondebug(boolean enabled) { this.getwgacore().getTestCore().setDebugAssertions(enabled); } @CodeCompletion public boolean isassertiondebug() { return this.getwgacore().getTestCore().isDebugAssertions(); } @CodeCompletion public void changesessionpassword(String domain, String newPassword) { // Fetch the login info for the current user DBLoginInfo loginInfo = (DBLoginInfo) getwgacore().getSessionLogins(gethttpsession()).get(domain); if (loginInfo == null) { return; } // Change password on login info loginInfo.setCredentials(newPassword); // Change cached password on domain auth module, if it is password-caching if (!WGDatabase.SESSIONTOKEN_USER.equals(loginInfo.getUserName())) { WGADomain domConfig = getwgacore().getDomains(domain); if (domConfig != null && domConfig.getAuthModule() instanceof PasswordCachingAuthenticationModule) { PasswordCachingAuthenticationModule module = (PasswordCachingAuthenticationModule) domConfig .getAuthModule(); module.dropPasswordCache(loginInfo.getUserName()); } } } @CodeCompletion public void changesessionpassword(String newPassword) throws WGAPIException { changesessionpassword((String) meta("db", "domain"), newPassword); } public TMLAction getActionByID(String id, String dbkey) { return getActionByID(id, dbkey, null); } /** * Retrieves an TMLAction definition from all valid sources * @param id The reference of the action * @param dbkey An explicitly chosen dbkey where to lookup the action. Give null if nothing was chosen. * @param baseRef The base design reference of the current design context, used to resolve the action. * @return */ public TMLAction getActionByID(String id, String dbkey, DesignResourceReference baseRef) { // Default action if (id.startsWith("$")) { return new TMLAction(id.substring(1)); } // If tag is present (WebTML-Environment) we can use action registration Map actionRegistration = getActionRegistration(); // First try: Search for registered action qualified by design db // If there are multiple actions with the same id (from different databases), we need to find the one defined for the current design database first Integer actionKey; String currentDesignKey = dbkey; if (currentDesignKey == null && baseRef != null) { currentDesignKey = baseRef.getDesignApp(); } if (currentDesignKey == null) { currentDesignKey = getDesignDBKey(); } TMLAction action = fetchActionByQualifiedId(id, currentDesignKey, actionRegistration); if (action != null) { return action; } // Second try: Search for module action in the current design db try { // Interpret id as module id DesignResourceReference moduleId = resolveDesignResource(dbkey, id, baseRef); // If the resolved id differs we will again try to fetch it from registration if (!moduleId.getResourceName().equals(id)) { action = fetchActionByQualifiedId(id, dbkey, actionRegistration); if (action != null) { return null; } } action = getModuleActionByID(moduleId.getResourceName(), moduleId.getDesignApp()); if (action != null) { return action; } } catch (Exception e) { getlog().error("Exception retrieving WebTML action " + currentDesignKey + "/" + id, e); addwarning(e.getMessage()); } // Third try: search for registered action, not qualified by dbkey. We can find actions registered by other DBs that way. actionKey = (Integer) actionRegistration.get("ID#" + id.toLowerCase()); if (actionKey != null) { action = (TMLAction) actionRegistration.get(actionKey); if (action != null && action.upToDate(this)) { return action; } } // No action found return null; } private TMLAction fetchActionByQualifiedId(String id, String dbkey, Map actionRegistration) { String qualifiedID = id; if (qualifiedID.indexOf("/") == -1) { qualifiedID = "ID#" + (dbkey + ACTIONID_DIVIDER + id).toLowerCase(); } TMLAction action = null; Integer actionKey = (Integer) actionRegistration.get(qualifiedID); if (actionKey != null) { TMLAction theAction = (TMLAction) actionRegistration.get(actionKey); if (theAction != null && theAction.upToDate(this)) { action = theAction; } } return action; } public String getDesignDBKey() { return _designContext.getDesignDB().getDbReference(); } public TMLAction getModuleActionByID(String id, String dbKey) throws TMLActionException { try { // Determine if there is dbkey information in the id List idParts = WGUtils.deserializeCollection(id, "/"); if (idParts.size() == 2) { dbKey = (String) idParts.get(0); id = (String) idParts.get(1); } // Get the design db. Either by dbkey in id, by parameter dbkey, by current design db of WebTML or just the current context db WGDatabase designDB; if (!WGUtils.isEmpty(dbKey)) { designDB = db(dbKey); } else { designDB = designdb(); } if (designDB == null) { throw new TMLActionException( "Could not open design db to load tmlscript action module, because it does not exist."); } if (!designDB.isSessionOpen()) { throw new TMLActionException("Could not open design db '" + designDB.getDbReference() + "' to load tmlscript action module, because you have no access."); } WGCSSJSModule mod = designDB.getCSSJSModule(id, WGScriptModule.CODETYPE_TMLSCRIPT); if (mod == null) { return null; } TMLAction action = TMLAction.buildActionFromScriptModule(mod); registerAction(action, id, designDB.getDbReference()); return action; } catch (WGException e) { throw new TMLActionException("Could not open design db to load tmlscript action module", e); } } @CodeCompletion public TMLForm createform(TMLFormInfo formInfo) throws WGException { TMLForm form = new TMLForm(getwgacore(), formInfo, this); _environment.setForm(form); return form; } @CodeCompletion public TMLFormInfo createforminfo(String id) { return new TMLFormInfo(id, TMLFormInfo.HTMLINPUT_FALSE, false, getDesignContext().getVersionCompliance()); } @CodeCompletion public TMLFormInfo createforminfo(String id, boolean htmlInput, boolean persistent) { return new TMLFormInfo(id, String.valueOf(htmlInput), true, getDesignContext().getVersionCompliance()); } /** * Takes a reference name that might be a local name (starting with ":"). * If it is a local name it will get expanded by the directory name of the currently executed module. * If it is not it will just get returned unmodified. * @param ref The reference name to expand * @param currentModuleRef The name of the currently executed module * @return The expanded name */ public static String processReferencePath(String ref, String currentModuleRef) { if (ref == null) { return ""; } // Local reference: Start with parent folder String startPath = ""; if (ref.startsWith("::")) { // Local reference, start with folder of current module ref if (currentModuleRef != null) { int colonPos = currentModuleRef.lastIndexOf(":"); if (colonPos != -1) { currentModuleRef = currentModuleRef.substring(0, colonPos); startPath = currentModuleRef; } } ref = ref.substring(2); if (ref.equals("")) return startPath; } // Process path parts; List<String> refParts = WGUtils.deserializeCollection(ref, ":"); List<String> currentParts = "".equals(startPath) ? new ArrayList<String>() : WGUtils.deserializeCollection(startPath, ":"); int idx = -1; for (String part : refParts) { idx++; if (part.equals("")) { if (idx == 0) { // A single colon at the start? Go up to the root. Else ignore. currentParts.clear(); } } else if (part.equals("..")) { // Go up one level if (idx == 0) { // At start: Use the parent folder of the base reference, otherwise just go up from wherever we are currentParts = "".equals(currentModuleRef) ? new ArrayList<String>() : WGUtils.deserializeCollection(currentModuleRef, ":"); } if (currentParts.size() > 0) { currentParts.remove(currentParts.size() - 1); } } else if (part.equals(".")) { // Stay on the current level if (idx == 0) { // At start: Use the current reference. Otherwise do nuffin currentParts = "".equals(currentModuleRef) ? new ArrayList<String>() : WGUtils.deserializeCollection(currentModuleRef, ":"); } } else { currentParts.add(part); } } // Return if (currentParts.size() == 0) { return ""; } else { return WGUtils.serializeCollection(currentParts, ":"); } } @CodeCompletion public WGResultSet lucenesearch(String phrase, String scope) throws WGQueryException { try { Map params = new HashMap(); scope = scope.toLowerCase(); if (scope.equals("wga")) { params.put(LuceneManager.QUERYOPTION_SEARCHSCOPE, LuceneManager.SEARCHSCOPE_WGA); } else if (scope.equals("domain")) { params.put(LuceneManager.QUERYOPTION_SEARCHSCOPE, LuceneManager.SEARCHSCOPE_DOMAIN); } else { params.put(LuceneManager.QUERYOPTION_SEARCHSCOPE, LuceneManager.SEARCHSCOPE_DB); } return getwgacore().getLuceneManager().search(db(), phrase, params, WGA.get(this)); } catch (WGException e) { if (e instanceof WGQueryException) { throw (WGQueryException) e; } else { throw new RuntimeException(e); } } } @CodeCompletion public WGResultSet lucenesearch(String phrase) throws WGQueryException { return lucenesearch(phrase, "db"); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#fileurl(java.lang.String, java.lang.String) */ @Override public String fileurl(String containerName, String fileName) throws WGException { return fileurl(null, containerName, fileName); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#fileurl(java.lang.String, java.lang.String, java.lang.String) */ @Override public String fileurl(String dbKey, String containerName, String fileName) throws WGException { WGAURLBuilder builder = getURLBuilder(); if (getDesignContext().getVersionCompliance().isAtLeast(7, 2) && builder instanceof WGASpecificFileURLBuilder) { return ((WGASpecificFileURLBuilder) builder).buildContentFileURL(toUnlockedVersion(), dbKey, containerName, fileName); } else { return builder.buildFileURL(toUnlockedVersion(), dbKey, containerName, fileName); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#fileurl(java.lang.String) */ @Override public String fileurl(String fileName) throws WGException { return fileurl(null, null, fileName); } public String filedataurl(String fileName) throws WGAPIException { return filedataurl(null, null, fileName, null, null); } public String filedataurl(String containerName, String fileName) throws WGAPIException { return filedataurl(null, containerName, fileName, null, null); } @Deprecated public String filedataurl(String containerName, String fileName, String contentType) throws WGAPIException { return filedataurl(null, containerName, fileName, contentType); } @Deprecated public String filedataurl(String dbKey, String containerName, String fileName, String contentType) throws WGAPIException { return filedataurl(dbKey, containerName, fileName, contentType, null); } public String filedataurl(String fileName, Map<String, String> config) throws WGAPIException { return filedataurl(config.get("designdb"), config.get("doc"), fileName, config.get("mimetype"), config.get("derivate")); } /** * creates a RFC2397 data url from the given file * @param dbKey * @param containerName * @param fileName * @param contentType * @return The url * @throws WGAPIException */ public String filedataurl(String dbKey, String containerName, String fileName, String contentType, String derivate) throws WGAPIException { // retrieve input stream InputStream fileIn = null; int fileSize = 0; try { // If containerName null get file from current content if (containerName == null) { fileIn = content().getFileData(fileName); fileSize = content().getFileSize(fileName); if (derivate != null) { // search for derivate: FileDerivateManager fdm = getwgacore().getFileDerivateManager(); DerivateQuery derivateQuery = fdm.parseDerivateQuery(derivate); WGFileAnnotations md = fdm.queryDerivate(content(), fileName, derivateQuery, new ClientHints(), true); if (md != null && md instanceof WGFileDerivateMetaData) { fileIn = content().getFileDerivateData(((WGFileDerivateMetaData) md).getId()); fileSize = (int) md.getSize(); } } if (fileIn == null) { addwarning("File '" + fileName + "' is not attached to content '" + content().getContentKey().toString() + "'."); return null; } } // Else try to find container else { DesignResourceReference containerRef = resolveDesignResource(dbKey, containerName); // get file from filecontainer WGDatabase designDB = db(containerRef.getDesignApp()); if (designDB == null) { addwarning("Unknown design db: " + dbKey); return null; } // first try - lookup file container of designDB or explicit given db WGDocument container = designDB.getFileContainer(containerRef.getResourceName()); if (container == null) { // second try - lookup file container in current context db container = db().getFileContainer(containerRef.getResourceName()); if (container == null) { // third try - use container name as key and try to find a content document container = WGPDispatcher.getContentByAnyKey(containerName, db(), new WebTMLLanguageChooser(db(), this), isbrowserinterface()); } } if (container == null) { addwarning("No file container or content found for '" + containerName + "'."); return null; } if (derivate != null && container instanceof WGContent) { // search for derivate: FileDerivateManager fdm = getwgacore().getFileDerivateManager(); DerivateQuery derivateQuery = fdm.parseDerivateQuery(derivate); WGFileAnnotations md = fdm.queryDerivate(container, fileName, derivateQuery, new ClientHints(), true); if (md != null && md instanceof WGFileDerivateMetaData) { fileIn = container.getFileDerivateData(((WGFileDerivateMetaData) md).getId()); fileSize = (int) md.getSize(); } } if (fileIn == null) { fileIn = container.getFileData(fileName); fileSize = container.getFileSize(fileName); } if (fileIn == null) { addwarning("File '" + fileName + "' not found in filecontainer '" + containerName + "'."); return null; } } } catch (WGException e) { addwarning("Error opening design db " + getDesignDBKey() + ": " + e.getClass().getName() + " - " + e.getMessage()); getwgacore().getLog().error("Error opening design db " + getDesignDBKey(), e); return null; } // Create the byte array to hold the data byte[] fileData = new byte[fileSize]; // read filedata in byte-array try { // Read in the bytes int offset = 0; int numRead = 0; while (offset < fileData.length && (numRead = fileIn.read(fileData, offset, fileData.length - offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read if (offset < fileData.length) { addwarning("Not all data could be readed from file '" + fileName + "'."); return null; } // close the stream fileIn.close(); } catch (IOException e) { addwarning("Unable to read file '" + fileName + "' from filecontainer '" + containerName + "' - " + e.getMessage()); getwgacore().getLog() .error("Unable to read file '" + fileName + "' from filecontainer '" + containerName + "'.", e); return null; } if (contentType == null && getEnvironment().isPageContextAvailable()) { // try to determine mime type contentType = getwgacore().getServletContext().getMimeType(fileName); } String url = createDataURL(fileData, contentType); if (url.length() > 65000) { addwarning("File " + fileName + ": data url size exeeds 65 KB: " + url.length() / 1000 + " KB."); } return createDataURL(fileData, contentType); } /** * creates a base64 encoded RFC2396 dataurl * @param data * @param contentType * @return */ private String createDataURL(byte data[], String contentType) { StringBuffer url = new StringBuffer(); url.append("data:"); if (contentType != null) { url.append(contentType); } url.append(";base64"); url.append("," + Base64.encode(data)); return url.toString(); } /** * creates an urlencoded RFC2396 dataurl * @param data * @return * @throws UnsupportedEncodingException * @throws URIException */ private String createDataURL(String data, String contentType) throws URIException { StringBuffer url = new StringBuffer(); url.append("data:"); if (contentType != null) { url.append(contentType); } // RFC2396 defines that data is encoded in US-ASCII url.append("," + URIUtil.encodeWithinPath(data, "UTF-8")); return url.toString(); } public void saveprofileonend() { if (!iswebenvironment()) { return; } TMLUserProfile prof = getprofile(); if (prof == null) { return; } prof.setSavedOnEnd(true); } @CodeCompletion public Map createlookuptable() { return WGA.get(this).createLookupTable(); } @CodeCompletion public Map createlookuptable(Map map) { return WGA.get(this).createLookupTable(map); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#createevent(java.lang.String) */ @Override public PortletEvent createevent(String name) { return new PortletEvent(name, _designContext.getVersionCompliance()); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isempty(java.lang.String) */ @Override public boolean isempty(String itemName) throws WGAPIException { Object item = item(itemName); return isemptyvalue(item); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isemptyvalue(java.lang.Object) */ @Override public boolean isemptyvalue(Object value) { if (value == null) { return true; } if (value instanceof List) { List list = (List) value; if (list.size() == 0) { return true; } } if (value instanceof String) { String string = (String) value; if (string.trim().equals("")) { return true; } // RTF-Editor sets a single <br> to a field when empty if (string.trim().equals("<br>")) { return true; } } return false; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isfilled(java.lang.String) */ @Override public boolean isfilled(String attValue) throws WGAPIException { boolean isEditmode = (isbrowserinterface() && content().getStatus().equals(WGContent.STATUS_DRAFT)); if (!isEditmode) { return !isempty(attValue); } else { return true; } } @CodeCompletion public boolean login(String user, String password, String domain) throws WGException { return getwgacore().login(user, password, domain, getrequest(), getresponse()); } public boolean login(String user, String password) throws WGException { return login(user, password, (String) db().getAttribute(WGACore.DBATTRIB_DOMAIN)); } @CodeCompletion public boolean logout(String domain) throws WGException { return getwgacore().logout(domain, getrequest().getSession(), getrequest(), getresponse(), true); } @CodeCompletion public WGDatabase plugindb(String pluginUniqueName) throws WGException { return db(plugindbkey(pluginUniqueName)); } @CodeCompletion public PluginID pluginid(String pluginUniqueName) throws WGException { WGAPlugin plugin = getwgacore().getPluginSet().getPluginByUniqueName(pluginUniqueName); if (plugin != null) { return plugin.getCsConfig().getPluginConfig().getId(); } else { return null; } } @CodeCompletion public String plugindbkey(String pluginUniqueName) { WGAPlugin plugin = getwgacore().getPluginSet().getPluginByUniqueName(pluginUniqueName); if (plugin != null) { return plugin.buildDatabaseKey(); } else { return null; } } @CodeCompletion public String encode(String encode, Object input) throws FormattingException { ObjectFormatter formatter = getwgacore().getEncodingFormatter(encode, this); if (formatter != null) { return formatter.format(input); } else { addwarning("No encoding formatter registered under encoding key '" + encode + "'"); return input.toString(); } } public String multiencode(String encode, Object input) throws FormattingException { FormattingChain formatters = new FormattingChain(); Iterator encoders = WGUtils.deserializeCollection(encode, ",", true).iterator(); while (encoders.hasNext()) { String encoder = (String) encoders.next(); ObjectFormatter formatter = getwgacore().getEncodingFormatter(encoder, this); formatters.addFormatter(formatter); } return formatters.format(input); } public WGAURLBuilder getURLBuilder() { return getEnvironment().getURLBuilder(); } @CodeCompletion public Document loadhtml(HttpClient client, String url) throws UnsupportedEncodingException, WGAPIException, IOException, HttpException, SAXException { try { return WGA.get(this).html().load(client, url); } catch (WGException e) { if (e instanceof WGAPIException) { throw (WGAPIException) e; } else { throw new WGAPIException(e); } } } @CodeCompletion public Document loadhtml(String url) throws UnsupportedEncodingException, WGAPIException, HttpException, IOException, SAXException { try { return WGA.get(this).html().load(url); } catch (WGException e) { if (e instanceof WGAPIException) { throw (WGAPIException) e; } else { throw new WGAPIException(e); } } } @CodeCompletion public Document parsehtml(String html) throws SAXException, IOException { try { return WGA.get(this).html().parse(html); } catch (WGException e) { throw new RuntimeException(e); } } /** * Registers an action for the current Http-Session, if an action with this code is not already registered. * Further code about this action object should use the object returned by this method, since that may be * a previous registered instance of it with the correct sequence number. * @param currentAction The action to register * @param id The id of the action. Specify null if the action has no id. * @return The action that is registered. Either the action given as parameter, or another one with identical code that already was registered */ public TMLAction registerAction(TMLAction currentAction, String id, String designDB) { TMLAction tmlAction; // Check if action registration available. If not, fail silent. Map actions = getActionRegistration(); if (actions == null) { return currentAction; } // check if action already exists if (!actions.containsKey(currentAction.getKey())) { // register new action actions.put(currentAction.getKey(), currentAction); tmlAction = currentAction; // store new action under tmlAction for further operations } else { // get registered action for further opertations tmlAction = (TMLAction) actions.get(currentAction.getKey()); } // register action id mapping if (id != null) { // Map with design db qualifier actions.put("ID#" + (designDB + TMLContext.ACTIONID_DIVIDER + id).toLowerCase(), currentAction.getKey()); // Map without design db qualifier actions.put("ID#" + id.toLowerCase(), currentAction.getKey()); currentAction.setID(id.toLowerCase()); } return tmlAction; } public void removePortletVariables(String prefix) { // Request variables Iterator varsIt = _environment.getPageVars().keySet().iterator(); String key; while (varsIt.hasNext()) { key = (String) varsIt.next(); if (key.startsWith(prefix)) { varsIt.remove(); } } // No longer necessary to clear session variables as they are now stored on portlet state } public String geturlparameter(String name) { return getrequest().getParameter(name); } public List geturlparameterlist(String name) { String[] values = getrequest().getParameterValues(name); List list = new ArrayList(); if (values != null) { for (int i = 0; i < values.length; i++) { list.add(values[i]); } } return list; } public List geturlparameternames() { return new ArrayList(getrequest().getParameterMap().keySet()); } public void seturlparameterifempty(String name, String value) throws WGIllegalStateException { if (getrequest() instanceof WGAFilter.RequestWrapper) { RequestWrapper wrapper = (WGAFilter.RequestWrapper) getrequest(); wrapper.setParameterIfEmpty(name, value); } else { throw new WGIllegalStateException("method setUrlParameterIfEmtpy() is only supported on GET requests."); } } public void seturlparameterifempty(String name, List values) throws WGIllegalStateException { if (getrequest() instanceof WGAFilter.RequestWrapper) { RequestWrapper wrapper = (WGAFilter.RequestWrapper) getrequest(); wrapper.setParameterIfEmpty(name, (String[]) values.toArray(new String[values.size()])); } else { throw new WGIllegalStateException("method setUrlParameterIfEmtpy() is only supported on GET requests."); } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isfirstloop() */ @Override public boolean isfirstloop() { BaseTagStatus tag = getDesignContext().getTag(); if (tag == null) { return false; } ForEach.Status targetTag = (ForEach.Status) tag.getAncestorTag(IterationTag.class); if (targetTag == null) { addwarning("Could not find ancestor iteration tag for method isfirstloop()."); return false; } return targetTag.getIterationIndex() == 1; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#islastloop() */ @Override public boolean islastloop() { BaseTagStatus tag = getDesignContext().getTag(); if (tag == null) { return false; } ForEach.Status targetTag = (ForEach.Status) tag.getAncestorTag(IterationTag.class); if (targetTag == null) { addwarning("Could not find ancestor iteration tag for method islastloop()."); return false; } return targetTag.isLastIteration(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isfirstloop(java.lang.String) */ @Override public boolean isfirstloop(String tagId) { BaseTagStatus tag = getDesignContext().getTag(); if (tag == null) { return false; } IterationTagStatus targetTag = (IterationTagStatus) tag.getTagStatusById(tagId, IterationTagStatus.class); if (targetTag == null) { addwarning("Could not find iteration tag with id '" + tagId + "'."); return false; } return targetTag.getIterationIndex() == 1; } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#islastloop(java.lang.String) */ @Override public boolean islastloop(String tagId) { BaseTagStatus tag = getDesignContext().getTag(); if (tag == null) { return false; } IterationTagStatus targetTag = (IterationTagStatus) tag.getTagStatusById(tagId, IterationTagStatus.class); if (targetTag == null) { addwarning("Could not find iteration tag with id '" + tagId + "'."); return false; } return targetTag.isLastIteration(); } public String resolveDBKey(String dbkey) { try { return WGA.get(this).design().resolveDbKey(dbkey); } catch (Exception e) { throw new RuntimeException("Exception resolving database key", e); } } /** * Ugly duplicate of {@link #pluginid(WGDatabase)}, kept for historical reasons. See B00005E92 * @param db * @return */ public PluginID getpluginid(WGDatabase db) { return pluginid(db); } @CodeCompletion public PluginID pluginid(WGDatabase db) { return (PluginID) db.getAttribute(WGACore.DBATTRIB_PLUGIN_ID); } public Map getPersistentForms() { return _environment.getPersistentForms(); } public TMLDesignContext getDesignContext() { return _designContext; } public ExpressionResult evaluateExpression(String expression, Map additionalObjects) { ExpressionEngine engine = ExpressionEngineFactory.getEngine(ExpressionEngineFactory.ENGINE_TMLSCRIPT); return engine.evaluateExpression(expression, this, ExpressionEngine.TYPE_EXPRESSION, additionalObjects); } public ExpressionResult evaluateExpression(String expression) { return evaluateExpression(expression, null); } public ExpressionResult evaluateScript(String script, Map additionalObjects) { ExpressionEngine engine = ExpressionEngineFactory.getEngine(ExpressionEngineFactory.ENGINE_TMLSCRIPT); return engine.evaluateExpression(script, this, ExpressionEngine.TYPE_SCRIPT, additionalObjects); } public ExpressionResult evaluateScript(String script) { return evaluateScript(script, null); } @CodeCompletion public void waitforauthupdates(WGDatabase db, int timeoutSeconds) throws WGAServerException { if (db == null) { db = db(); } // Collect the CSAuthModules listening to content save events on this database List listeners = db.getContentEventListeners(); List modules = new ArrayList(); synchronized (listeners) { Iterator it = listeners.iterator(); while (it.hasNext()) { WGContentEventListener listener = (WGContentEventListener) it.next(); if (listener instanceof CSAuthModule) { modules.add(listener); } } } // Look thru the modules until their currently running update threads have finished long timeout = System.currentTimeMillis() + (timeoutSeconds * 1000); Map moduleThreads = new HashMap(); do { // Idle. Check timeout try { Thread.sleep(100); } catch (InterruptedException e) { } if (System.currentTimeMillis() > timeout) { throw new WGAServerException( "Method waitForAuthUpdates() encountered timout of " + timeoutSeconds + "seconds"); } // Iterate modules Iterator modIt = modules.iterator(); while (modIt.hasNext()) { CSAuthModule mod = (CSAuthModule) modIt.next(); // Look if a collector runs right now. If not, then this module is thru if (mod.getCurrentCollectorThread() == null) { modIt.remove(); } // A collection runs right now. else { // Retrieve an maybe recorded earlier thread Thread earlierThread = (Thread) moduleThreads.get(mod); // if there is no earlier thread then we just haven't recorded it yet if (earlierThread == null) { moduleThreads.put(mod, mod.getCurrentCollectorThread()); } // If there was an earlier thread, we look if it is still the same. If not, the earlier thread is finished and our update most likely thru else if (!earlierThread.equals(mod.getCurrentCollectorThread())) { modIt.remove(); } } } } while (modules.size() > 0); } /** * Retrieves a WGA internal system label from the properties files lying under {@link WGACore#SYSTEMLABEL_BASE_PATH} in the language of the current request locale * @param systemBundleName Name of the bundle file * @param labelKey Key of the label * @param params A list of parameters that replace placeholders {1}...{n} in the label * @return The label or an empty string if none was found */ public String systemLabel(String systemBundleName, String labelKey, List params) { try { return WGA.get(this).design().systemLabel(systemBundleName, labelKey, params); } catch (WGException e) { this.addwarning(e.getMessage(), false); return ""; } } public String systemLabel(String systemBundleName, String labelKey) { return systemLabel(systemBundleName, labelKey, null); } public static TMLContext createMasterSessionContext(TMLContext context) throws WGAPIException { if (context.getdocument().isTemporary() && !context.getdocument().isDummy()) { throw new WGIllegalArgumentException("Context document '" + context.getdocument().getDocumentKey() + "' is temporary and cannot be used as context when switching to master session"); } TMLContext mainContext = context.getmaincontext(); TMLContext masterMainContext = new TMLContext(mainContext.getdocument(), mainContext.getwgacore(), context.getprofile(), context.gettmlform()).designContext(context.getDesignContext()); TMLContext masterContext; if (!context.getdocument().equals(masterMainContext.getdocument())) { masterContext = masterMainContext.context(context.getdocument()); if (masterContext == null) { throw new WGIllegalDataException("Unretrievable master action context: " + context.getpath()); } } else { masterContext = masterMainContext; } try { masterContext.importEnvironmentData(context); } catch (TMLException e) { context.getlog().error("Error importing TMLScript environment settings", e); } return masterContext; } public static Map<String, TransientObjectWrapper<Object>> fetchSessionVars(HttpSession session) { @SuppressWarnings("unchecked") Map<String, TransientObjectWrapper<Object>> sessionVars = (Map<String, TransientObjectWrapper<Object>>) session .getAttribute(WGPDispatcher.SESSION_VARS); if (sessionVars == null) { sessionVars = new ConcurrentHashMap<String, TransientObjectWrapper<Object>>(); session.setAttribute(WGPDispatcher.SESSION_VARS, sessionVars); } return sessionVars; } public static ProcessContextRegistration fetchProcessContextRegistration(HttpSession session) { ProcessContextRegistration reg = (ProcessContextRegistration) session .getAttribute(SESSIONATTRIB_PROCESSCONTEXTS); if (reg == null) { reg = new ProcessContextRegistration(); session.setAttribute(TMLContext.SESSIONATTRIB_PROCESSCONTEXTS, reg); } return reg; } public static Map<String, TMLAction> fetchActionRegistration(HttpSession session) { @SuppressWarnings("unchecked") Map<String, TMLAction> actionRegistration = (Map<String, TMLAction>) session .getAttribute(WGACore.SESSION_ACTIONS); if (actionRegistration == null) { actionRegistration = new ConcurrentHashMap<String, TMLAction>(); session.setAttribute(WGACore.SESSION_ACTIONS, actionRegistration); } return actionRegistration; } public static TMLUserProfile fetchUserProfile(WGACore core, WGDatabase db, HttpServletRequest req, HttpServletResponse res) { try { return core.getPersManager().fetchUserProfile(req, res, db); } catch (WGAPIException e) { core.getLog().error("Unable to retrieve user profile", e); } return null; } public static List<Warning> fetchWarnings(HttpServletRequest req) { @SuppressWarnings("unchecked") List<Warning> warnings = (List<Warning>) req.getAttribute(Base.class.getName() + ":Warnings"); if (warnings == null) { warnings = new ArrayList<Warning>(); req.setAttribute(Base.class.getName() + ":Warnings", warnings); } return warnings; } public static Map<String, TMLForm> fetchTransientForms(HttpServletRequest req) { @SuppressWarnings("unchecked") Map<String, TMLForm> forms = (Map<String, TMLForm>) req.getAttribute(WGACore.ATTRIB_TMLFORM); if (forms == null) { forms = new HashMap<String, TMLForm>(); req.setAttribute(WGACore.ATTRIB_TMLFORM, forms); } return forms; } @SuppressWarnings("unchecked") public static Map<String, TMLForm> fetchPersistentForms(HttpSession session) { Map<String, TMLForm> forms = (Map<String, TMLForm>) session.getAttribute(WGACore.ATTRIB_TMLFORM); if (forms == null) { forms = new HashMap<String, TMLForm>(); session.setAttribute(WGACore.ATTRIB_TMLFORM, forms); } return forms; } public WGUserAccess getoriginaluserdata() { RootEnvironmentUserData userData = getEnvironment().getRootEnvironmentUserData(); // We have no root environment data = we are in root environment. So we return the current db user access if (userData == null) { return db().getSessionContext().getUserAccess(); } // We return root environment data only if it matches the database currently in context if (userData.getDbkey().equals(db().getDbReference())) { return userData.getUserAccess(); } // We have root environment data, but it does not match the current context db = we have no data for the current db. So return null. else { return null; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#removetmlform(java.lang.String) */ @Override public void removetmlform(String formid) { _environment.removeForm(formid); } public void attachscaledimage(WGDocument doc, ImageScaler scaler, String targetFileName) throws IOException, WGAPIException { // Determine final file name String finalFileName = null; if (targetFileName != null) { finalFileName = targetFileName + scaler.getFormatSuffix(); } else { String fileName = scaler.getSourceFileName(); if (fileName == null) { throw new IllegalArgumentException( "Unable to determine file name. Please specify as targetFileName."); } String suffix = null; if (scaler.getFormat().equals("JPEG")) { suffix = ".jpg"; } else if (scaler.getFormat().equals("PNG")) { suffix = ".png"; } finalFileName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix; } TemporaryFile targetFile = new TemporaryFile(finalFileName, null, WGFactory.getTempDir()); targetFile.deleteOnEviction(doc.getDatabase().getSessionContext()); // Write scaled image to target file scaler.writeImage(targetFile.getFile()); // Attach scaled image doc.attachFile(targetFile.getFile()); } public void attachscaledimage(WGDocument doc, ImageScaler scaler) throws IOException, WGAPIException { attachscaledimage(doc, scaler, null); } public TMLContext dbContext(WGDatabase dbTarget, WGLanguageChooser chooser) throws WGAPIException { WGLanguage lang = chooser.selectDatabaseLanguage(dbTarget); // We want to create a db context even when there is no matching language // so we just create dummy content on the source context language if (lang == null) { lang = dbTarget.getLanguage(content().getLanguage().getName()); } WGContent dummyContent = dbTarget.getDummyContent(lang.getName()); if (dummyContent != null) { return getTMLContextForDocument(dummyContent); } else { return null; } } public TMLContext dbContext(WGDatabase dbTarget) throws WGAPIException { try { return (TMLContext) WGA.get(this).createTMLContext(dbTarget); } catch (WGException e) { // Tedious and ugly cause determination to keep exception signature of this legacy method if (e.getCause() instanceof WGAPIException) { throw (WGAPIException) e.getCause(); } else { throw new WGAPIException("Exception creating db context", e); } } } public BaseTagStatus gettag() { return getDesignContext().getTag(); } public List<Warning> getWarnings() { return getEnvironment().getWarnings(); } public DesignResourceReference resolveDesignResource(String ref) throws WGException { return resolveDesignResource(null, ref, null); } public DesignResourceReference resolveDesignResource(String designDB, String refString) throws WGException { return resolveDesignResource(designDB, refString, null); } public DesignResourceReference resolveDesignResource(String refString, DesignResourceReference baseReference) throws WGException { return resolveDesignResource(null, refString, baseReference); } /** * Resolves a design reference to find the corresponding resource. * Takes care of all special addressation forms: * <ul> * <li>Local references * <li>dbkeys addressed inside the refString with "dbkey/" syntax * <li>@base * @param refDB dbkey of an explicitly chosen target app. Give null if nothing was chosen. * @param refString The reference string addressing the resource * @param baseReference The base reference used to resolve relative addressation * @return A design resource reference object, with resolved appdb/resource name * @throws WGException */ public DesignResourceReference resolveDesignResource(String refDB, String refString, DesignResourceReference baseReference) throws WGException { Design design = WGA.get(this).design(); if (baseReference != null) { design = design.resolve(baseReference); } return design.resolveReference(new DesignResourceReference(refDB, refString)); } public String getScopedString(String str, String scope) { try { return WGA.get(this).scoped(str, scope); } catch (WGException e) { // Cannot happen when scope is provided return str; } } public List<String> buildOptions(Iterable<WGContent> contents, String titleExpr, String emptyTitle) throws WGAPIException { try { return WGA.get(this).buildOptions(contents, titleExpr, emptyTitle); } catch (WGException e) { // Cannot happen return null; } } public String scripturl(String dbKey, String type, String doc) throws WGException { return getURLBuilder().buildScriptURL(this, dbKey, type, doc); } public String scripturl(String type, String doc) throws WGException { return getURLBuilder().buildScriptURL(this, getDesignDBKey(), type, doc); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#istagidvalid(java.lang.String) */ @Override public boolean istagidvalid(String tagid) { BaseTagStatus status = getDesignContext().getTag(); if (status != null) { return (status.getTagStatusById(tagid) != null ? true : false); } else { return false; } } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#hasrole(java.lang.String) */ @Override public boolean hasrole(String role) throws WGAPIException { return metalist("db", "userroles").contains(role); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#hasgroup(java.lang.String) */ @Override public boolean hasgroup(String group) throws WGAPIException { return metalist("db", "usergroups").contains(group); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#isanonymous() */ @Override public boolean isanonymous() throws WGAPIException { return db().getSessionContext().isAnonymous(); } /* (non-Javadoc) * @see de.innovationgate.wgpublisher.webtml.utils.Context#appendvar(java.lang.String, java.lang.Object) */ @Override public void appendvar(String name, Object value) throws WGAPIException { try { Object oldValue = retrieveVar(name); List newValue; if (oldValue instanceof NullPlaceHolder) { newValue = new ArrayList(); } else { newValue = toList(oldValue); } if (value instanceof Collection) { newValue.addAll((Collection) value); } else { newValue.add(value); } updateOrSetVar(name, newValue); } catch (WGException e) { throw new WGAPIException(e); } } @Override public String toString() { try { return getpath(); } catch (WGAPIException e) { return super.toString(); } } public String getUriHash() { return (String) getrequest().getAttribute(WGACore.ATTRIB_URI_HASH); } public DerivateQuery enhanceFileDerivateQuery(String fileDerivates) throws WGInvalidDerivateQueryException { String existingDerivates = (String) option(Base.OPTION_IMAGE_DERIVATES); DerivateQuery derivateQuery; if (existingDerivates != null) { derivateQuery = getwgacore().getFileDerivateManager().mergeDerivateQueries(fileDerivates, existingDerivates); } else { derivateQuery = getwgacore().getFileDerivateManager().parseDerivateQuery(fileDerivates); } return derivateQuery; } public TMLContext designContext(TMLDesignContext designContext) { return new TMLContext(this, designContext); } public TMLContext designContext(String baseReference) { return designContext(_designContext.createContextDelegate(_designContext.getDesignDB(), baseReference)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((document == null) ? 0 : document.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TMLContext other = (TMLContext) obj; if (document == null) { if (other.document != null) return false; } else if (!document.equals(other.document)) return false; return true; } public PortletEvent fetchRequestPortletEvent() { // Event originally thrown from server String eventIdxStr = getrequest().getParameter("$portletEvent"); if (!WGUtils.isEmpty(eventIdxStr)) { Long eventIdx = Long.parseLong(eventIdxStr); PortletEvent event = findEventByIndex(eventIdx); if (event != null) { return event; } } // Event originally thrown by browser client. We just instantiate an event of the given name, but have no parameters and such String eventName = getrequest().getParameter("$portletEventName"); if (!WGUtils.isEmpty(eventName)) { PortletEvent event = new PortletEvent(eventName, getDesignContext().getVersionCompliance()); try { String eventParams = getwgacore().getURLEncoder() .decode(getrequest().getParameter("$portletEventParams")); if (eventParams != null) { event.setParameters(new Gson().fromJson(eventParams, Map.class)); } } catch (Exception e) { getlog().error("Exception decoding portlet event parameters from JSON", e); } return event; } return null; } private PortletEvent findEventByIndex(Long eventIdx) { LinkedMap events = TMLPortlet.getFiredEventsQueue(gethttpsession()); return (PortletEvent) events.get(eventIdx); } public boolean isCurrentSequenceNumber(TMLActionLink actionLink, HttpSession session, boolean ajax) { boolean correctSequence = true; // In case of norefresh actions we do not care about debouncing if (actionLink.getMode() != null && actionLink.getMode().equals(TMLActionLink.MODE_AJAX_NO_PORTLET_REFRESH)) { return true; } if (actionLink.isDefaultAction()) { TMLAction action = new TMLAction(actionLink.getDefaultAction()); TMLAction.DefaultAction defaultAction = TMLAction.getDefaultAction(action); // When default action is unknown return true, // so the action execution runs and issues warning "unknown default action" if (defaultAction == null) { return true; } // if debouncing is disabled we do not care about sequencenumber if (!action.isDebounce()) { return true; } if (!getwgacore().defaultActionSequenceIdAlreadyUsed(actionLink.getSequenceId())) { getwgacore().defaultActionCalledWithSequenceId(actionLink.getSequenceId()); } else { correctSequence = false; } } else { TMLAction action = (TMLAction) getActionRegistration().get(actionLink.getActionKeyInteger()); if (action == null) { // Will fail later when action will be called. More speaking error message can be put out there. return true; } // if debouncing is disabled we do not care about sequencenumber if (!action.isDebounce()) { return true; } if (!action.sequenceIdAlreadyUsed(actionLink.getSequenceId())) { // action was not called with this sequenceId action.calledWithSequenceId(actionLink.getSequenceId()); } else { correctSequence = false; } } return correctSequence; } public ManagedObject fetchModuleController() throws WGException { DesignResourceReference currentModule = getDesignContext().getBaseReference(); final Design mcDesign = WGA.get(this).design().resolve(currentModule) .resolve("::" + currentModule.getResourceLocalName() + ".controller"); // Inside WebTML page return the existing module controller from option ManagedObject mc = (ManagedObject) option(Base.OPTION_MODULE_CONTROLLER); if (mc != null && mc.getDesign().equals(mcDesign.getBaseReference())) { return mc; } TMLContext controllerContext = designContext(mcDesign.getBaseReference().toString()); WGA wga = WGA.get(controllerContext); // If the design is the same as for the portlet then the portlet controller is module controller TMLPortlet portlet = getportlet(); if (portlet != null && !portlet.isroot()) { DesignResourceReference portletControllerDesign = portlet.getState().getControllerDesign(); if (mcDesign.getBaseReference().equals(portletControllerDesign)) { ScopeObject portletController = portlet.getState().fetchController(wga); if (portletController != null) { return portletController; } } } // Create module controller WGScriptModule rendererModule = mcDesign.getScriptModule(WGScriptModule.CODETYPE_TMLSCRIPT); if (rendererModule == null) { return null; } TMLScript tmlscript = wga.tmlscript(); final Object createdMc = wga.tmlscript().createObject(mcDesign, ObjectType.V2_ISOLATED); return new ManagedObject() { @Override public void afterUsage() { } @Override public void beforeUsage() throws WGException { } @Override public Object getObject() { return createdMc; } @Override public DesignResourceReference getDesign() { return mcDesign.getBaseReference(); } }; } public TMLContext toIsolatedVersion() { if (!(_environment instanceof IsolatedTMLContextEnvironment)) { TMLContext isolatedContext = new TMLContext(this.document, getwgacore(), getprofile(), gettmlform(), getrequest(), getresponse(), gethttpsession()); isolatedContext.isolate(); return isolatedContext; } else { return this; } } private TMLContext toUnlockedVersion() { if (_environment instanceof IsolatedTMLContextEnvironment) { TMLContextEnvironment unlockedEnv = ((IsolatedTMLContextEnvironment) _environment) .getParentEnvironment(); return new TMLContext(this.document, getwgacore(), getprofile(), unlockedEnv.getForm(), unlockedEnv.getRequest(), unlockedEnv.getResponse(), unlockedEnv.getSession()); } else { return this; } } protected boolean isEnhancedItemExpressions() { return getDesignContext().getVersionCompliance().isAtLeast(7, 2) || getDesignContext().getDesignDB() .getBooleanAttribute(WGACore.DBATTRIB_ENHANCED_ITEMEXPRESSIONS, false); } public void setLocalVar(String name, Object value) throws WGException { name = convertVarName(name); getDesignContext().setLocalVar(name, value); } private void isolate() { if (!(_environment instanceof IsolatedTMLContextEnvironment)) { _environment = new IsolatedTMLContextEnvironment(this, getEnvironment().getCore(), getprofile(), getEnvironment().getForm(), getEnvironment().getRequest(), getEnvironment().getResponse(), getEnvironment().getSession()); } } @Override public boolean ishomepage() { if (getcontent().isDummy()) return false; String homepageName = (String) db().getAttribute(WGACore.DBATTRIB_HOME_PAGE_NAME); if (homepageName != null) { try { String name = getcontent().getStructEntry().getUniqueName(); if (name == null) name = getcontent().getUniqueName(); if (name != null && name.equalsIgnoreCase(homepageName)) return true; } catch (WGAPIException e) { } } return false; } @Override public String loginurl() throws WGException { return getURLBuilder().buildLoginURL(db(), getrequest(), contenturl()); } }