package com.celements.appScript; import java.io.IOException; import java.util.List; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.Requirement; import org.xwiki.context.Execution; import org.xwiki.model.EntityType; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.EntityReferenceValueProvider; import org.xwiki.model.reference.SpaceReference; import org.xwiki.model.reference.WikiReference; import com.celements.emptycheck.service.IEmptyCheckRole; import com.celements.web.service.IWebUtilsService; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.util.Util; @Component public class AppScriptService implements IAppScriptService { private static Log LOGGER = LogFactory.getFactory().getInstance(AppScriptService.class); @Requirement IEmptyCheckRole emptyCheck; @Requirement IWebUtilsService webUtils; @Requirement Execution execution; @Requirement EntityReferenceValueProvider defaultEntityReferenceValueProvider; private XWikiContext getContext() { return (XWikiContext) execution.getContext().getProperty("xwikicontext"); } public int getStartIndex(String path) { String actionName = getAppActionName(); return path.indexOf("/" + actionName + "/") + actionName.length() + 2; } public String getAppActionName() { return getContext().getWiki().Param(APP_SCRIPT_ACTION_NAME_CONF_PROPERTY, APP_SCRIPT_XPAGE); } public boolean hasDocAppScript(String scriptName) { boolean hasDocAppScript = hasLocalAppScript(scriptName) || hasCentralAppScript(scriptName); LOGGER.debug("hasDocAppScript: scriptName [" + scriptName + "] hasDocAppScript [" + hasDocAppScript + "]"); return hasDocAppScript; } public boolean hasLocalAppScript(String scriptName) { return !"".equals(scriptName) && docAppScriptExists(getLocalAppScriptDocRef(scriptName)); } private boolean docAppScriptExists(DocumentReference appScriptDocRef) { boolean existsAppScriptDoc = getContext().getWiki().exists(appScriptDocRef, getContext()); boolean isNotEmptyAppScriptDoc = !emptyCheck.isEmptyRTEDocument(appScriptDocRef); LOGGER.debug("docAppScriptExists check [" + appScriptDocRef + "]: exists [" + existsAppScriptDoc + "] isNotEmpty [" + isNotEmptyAppScriptDoc + "]"); return (existsAppScriptDoc && isNotEmptyAppScriptDoc); } public boolean hasCentralAppScript(String scriptName) { return !"".equals(scriptName) && docAppScriptExists(getCentralAppScriptDocRef(scriptName)); } public DocumentReference getAppScriptDocRef(String scriptName) { if (hasLocalAppScript(scriptName)) { return getLocalAppScriptDocRef(scriptName); } else { return getCentralAppScriptDocRef(scriptName); } } public DocumentReference getLocalAppScriptDocRef(String scriptName) { return new DocumentReference(getContext().getDatabase(), APP_SCRIPT_SPACE_NAME, scriptName); } public DocumentReference getCentralAppScriptDocRef(String scriptName) { return new DocumentReference("celements2web", APP_SCRIPT_SPACE_NAME, scriptName); } public String getAppScriptTemplatePath(String scriptName) { return "celAppScripts/" + scriptName + ".vm"; } public boolean isAppScriptAvailable(String scriptName) { try { String path = "/templates/" + getAppScriptTemplatePath(scriptName); LOGGER.debug("isAppScriptAvailable: check on [" + path + "]."); getContext().getWiki().getResourceContentAsBytes(path); LOGGER.trace("isAppScriptAvailable: Successful got app script [" + scriptName + "]."); return true; } catch (IOException exp) { LOGGER.debug("isAppScriptAvailable: Failed to get app script [" + scriptName + "].", exp); return false; } } public String getAppScriptURL(String scriptName) { return getAppScriptURL(scriptName, ""); } public String getAppScriptURL(String scriptName, String queryString) { if (queryString == null) { queryString = ""; } if (queryString.length() > 0 && !queryString.startsWith("/&")) { queryString = "&" + queryString; } queryString = "xpage=" + IAppScriptService.APP_SCRIPT_XPAGE + "&s=" + scriptName + queryString; if (scriptName.split("/").length <= 2) { return getContext().getWiki().getURL(webUtils.resolveDocumentReference(scriptName.replaceAll( "/", ".")), "view", queryString, null, getContext()); } else { return Util.escapeURL("/app/" + scriptName + "?" + queryString); } } public boolean isAppScriptCurrentPage(String scriptName) { String scriptStr = getScriptNameFromURL(); return (!"".equals(scriptStr) && (scriptStr.equals(scriptName))); } public String getScriptNameFromDocRef(DocumentReference docRef) { String spaceName = docRef.getLastSpaceReference().getName(); if (spaceName.equals(defaultEntityReferenceValueProvider.getDefaultValue(EntityType.SPACE))) { return docRef.getName(); } else { return spaceName + "/" + docRef.getName(); } } public String getScriptNameFromURL() { String scriptStr = ""; if (isAppScriptRequest()) { scriptStr = getAppScriptNameFromRequestURL(); } else { LOGGER.debug("getScriptNameFromURL: no AppScriptRequest thus returning ''."); } return scriptStr; } public boolean isAppScriptRequest() { // TODO exclude isOverlayRequest return isAppScriptXpageRequest() || isAppScriptActionRequest() || isAppScriptSpaceRequest() || isAppScriptOverwriteDocRef(getContext().getDoc().getDocumentReference()); } public boolean isAppScriptOverwriteDocRef(DocumentReference docRef) { String overwriteAppDocs = getContext().getWiki().getXWikiPreference( APP_SCRIPT_XWPREF_OVERW_DOCS, APP_SCRIPT_CONF_OVERW_DOCS, "-", getContext()); List<DocumentReference> overwAppDocList = new Vector<DocumentReference>(); if (!"-".equals(overwriteAppDocs)) { for (String overwAppDocFN : overwriteAppDocs.split("[, ]")) { try { DocumentReference overwAppDocRef = webUtils.resolveDocumentReference(overwAppDocFN); overwAppDocList.add(overwAppDocRef); } catch (Exception exp) { LOGGER.warn("Failed to parse appScript overwrite docs config part [" + overwAppDocFN + "] of complete config [" + overwriteAppDocs + "]."); } } } return overwAppDocList.contains(docRef); } private boolean isAppScriptActionRequest() { Object appAction = getContext().get("appAction"); return (appAction != null) && ((Boolean) appAction); } private boolean isAppScriptSpaceRequest() { return "view".equals(getContext().getAction()) && getContext().getDoc().getDocumentReference().getSpaceReferences().contains( getCurrentSpaceRef()); } private SpaceReference getCurrentSpaceRef() { return new SpaceReference(APP_SCRIPT_XPAGE, new WikiReference(getContext().getDatabase())); } private boolean isAppScriptXpageRequest() { String xpageStr = getContext().getRequest().getParameter("xpage"); return APP_SCRIPT_XPAGE.equals(xpageStr) && (getAppScriptNameFromRequestURL() != null); } String getAppScriptNameFromRequestURL() { if (isAppScriptActionRequest() || isAppScriptSpaceRequest()) { String path = getContext().getRequest().getPathInfo(); return path.substring(getStartIndex(path)).replaceAll("^/+", ""); } else if (isAppScriptOverwriteDocRef(getContext().getDoc().getDocumentReference())) { String path = getContext().getRequest().getPathInfo().replaceAll("^/+", ""); if (path.startsWith(getContext().getAction())) { path = path.replaceAll("^" + getContext().getAction() + "/+", ""); } path = path.replaceFirst("^" + defaultEntityReferenceValueProvider.getDefaultValue( EntityType.SPACE) + "/", ""); if ("".equals(path)) { path = defaultEntityReferenceValueProvider.getDefaultValue(EntityType.DOCUMENT); } else if (path.endsWith("/")) { path += defaultEntityReferenceValueProvider.getDefaultValue(EntityType.DOCUMENT); } return path; } return getContext().getRequest().getParameter("s"); } }