/*
* Copyright (C) 2003-2010 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.wiki.commons;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.portlet.PortletPreferences;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.exoplatform.commons.utils.MimeTypeResolver;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.container.RootContainer;
import org.exoplatform.download.DownloadService;
import org.exoplatform.download.InputStreamDownloadResource;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.UserACL;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.webui.portal.UIPortal;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.services.jcr.access.AccessControlEntry;
import org.exoplatform.services.jcr.access.AccessControlList;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.Identity;
import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.application.portlet.PortletRequestContext;
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.form.UIForm;
import org.exoplatform.webui.form.UIFormSelectBox;
import org.exoplatform.webui.form.UIFormTextAreaInput;
import org.exoplatform.wiki.chromattic.ext.ntdef.NTVersion;
import org.exoplatform.wiki.mow.api.Page;
import org.exoplatform.wiki.mow.api.Wiki;
import org.exoplatform.wiki.mow.api.WikiNodeType;
import org.exoplatform.wiki.mow.api.WikiType;
import org.exoplatform.wiki.mow.core.api.MOWService;
import org.exoplatform.wiki.mow.core.api.WikiStoreImpl;
import org.exoplatform.wiki.mow.core.api.wiki.PageImpl;
import org.exoplatform.wiki.mow.core.api.wiki.Preferences;
import org.exoplatform.wiki.mow.core.api.wiki.WikiImpl;
import org.exoplatform.wiki.rendering.RenderingService;
import org.exoplatform.wiki.rendering.impl.RenderingServiceImpl;
import org.exoplatform.wiki.resolver.PageResolver;
import org.exoplatform.wiki.service.Permission;
import org.exoplatform.wiki.service.PermissionEntry;
import org.exoplatform.wiki.service.WikiContext;
import org.exoplatform.wiki.service.WikiPageParams;
import org.exoplatform.wiki.service.WikiService;
import org.exoplatform.wiki.service.impl.SessionManager;
import org.exoplatform.wiki.tree.utils.TreeUtils;
import org.exoplatform.wiki.webui.UIWikiPageEditForm;
import org.exoplatform.wiki.webui.UIWikiPortlet;
import org.exoplatform.wiki.webui.UIWikiRichTextArea;
import org.exoplatform.wiki.webui.WikiMode;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.rendering.syntax.Syntax;
/**
* Created by The eXo Platform SAS
* Author : viet nguyen
* viet.nguyen@exoplatform.com
* Apr 22, 2010
*/
public class Utils {
public static final String WITH = "With";
public static final int DEFAULT_VALUE_UPLOAD_PORTAL = -1;
public static String getCurrentRequestURL() throws Exception {
PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
HttpServletRequest request = portalRequestContext.getRequest();
String requestURL = request.getRequestURL().toString();
UIPortal uiPortal = Util.getUIPortal();
String pageNodeSelected = uiPortal.getSelectedUserNode().getURI();
if (!requestURL.contains(pageNodeSelected)) {
// Happens at the first time processRender() called when add wiki portlet manually
requestURL = portalRequestContext.getPortalURI() + pageNodeSelected;
}
return requestURL;
}
public static WikiPageParams getCurrentWikiPageParams() throws Exception {
String requestURL = getCurrentRequestURL();
PageResolver pageResolver = (PageResolver) PortalContainer.getComponent(PageResolver.class);
WikiPageParams params = pageResolver.extractWikiPageParams(requestURL, Util.getUIPortal().getSelectedUserNode());
HttpServletRequest request = Util.getPortalRequestContext().getRequest();
Map<String, String[]> paramsMap = request.getParameterMap();
params.setParameters(paramsMap);
return params;
}
public static Page getCurrentWikiPage() throws Exception {
String requestURL = Utils.getCurrentRequestURL();
Page helpPage = isRenderFullHelpPage();
if (helpPage != null) {
return helpPage;
}
PageResolver pageResolver = (PageResolver) PortalContainer.getComponent(PageResolver.class);
Page page = pageResolver.resolve(requestURL, Util.getUIPortal().getSelectedUserNode());
return page;
}
public static String getURLFromParams(WikiPageParams params) throws Exception {
PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
String requestURL = portalRequestContext.getRequest().getRequestURL().toString();
String portalURI = portalRequestContext.getPortalURI();
String domainURL = requestURL.substring(0, requestURL.indexOf(portalURI));
UIPortal uiPortal = Util.getUIPortal();
String pageNodeSelected = uiPortal.getSelectedUserNode().getURI();
StringBuilder sb = new StringBuilder(domainURL);
sb.append(portalURI);
sb.append(pageNodeSelected);
sb.append("/");
if (!PortalConfig.PORTAL_TYPE.equalsIgnoreCase(params.getType())) {
sb.append(params.getType().toLowerCase());
sb.append("/");
sb.append(org.exoplatform.wiki.utils.Utils.validateWikiOwner(params.getType(),
params.getOwner()));
sb.append("/");
}
sb.append(URLEncoder.encode(params.getPageId(), "UTF-8"));
return sb.toString();
}
public static Page getCurrentNewDraftWikiPage() throws Exception {
WikiService wikiService = (WikiService) PortalContainer.getComponent(WikiService.class);
String sessionId = Util.getPortalRequestContext().getRequest().getSession(false).getId();
return wikiService.getExsitedOrNewDraftPageById(null, null, sessionId);
}
public static String getDownloadLink(String path, String filename, DownloadService dservice){
if(dservice == null)dservice = (DownloadService)PortalContainer.getComponent(DownloadService.class) ;
WikiService wservice = (WikiService)PortalContainer.getComponent(WikiService.class) ;
try {
InputStream input = wservice.getAttachmentAsStream(path) ;
byte[] attBytes = null;
if (input != null) {
attBytes = new byte[input.available()];
input.read(attBytes);
ByteArrayInputStream bytearray = new ByteArrayInputStream(attBytes);
MimeTypeResolver mimeTypeResolver = new MimeTypeResolver() ;
String mimeType = mimeTypeResolver.getMimeType(filename) ;
InputStreamDownloadResource dresource = new InputStreamDownloadResource(bytearray, mimeType);
dresource.setDownloadName(filename);
return dservice.getDownloadLink(dservice.addDownloadResource(dresource));
}
} catch (Exception e) {
}
return null;
}
public static String getExtension(String filename)throws Exception {
MimeTypeResolver mimeResolver = new MimeTypeResolver() ;
try{
return mimeResolver.getExtension(mimeResolver.getMimeType(filename)) ;
}catch(Exception e) {
return mimeResolver.getDefaultMimeType() ;
}
}
public static Wiki getCurrentWiki() throws Exception {
MOWService mowService = (MOWService) PortalContainer.getComponent(MOWService.class);
WikiStoreImpl store = (WikiStoreImpl) mowService.getModel().getWikiStore();
String wikiType= Utils.getCurrentWikiPageParams().getType();
String owner= Utils.getCurrentWikiPageParams().getOwner();
return store.getWiki(WikiType.valueOf(wikiType.toUpperCase()), owner);
}
public static WikiContext setUpWikiContext(UIWikiPortlet wikiPortlet) throws Exception {
RenderingService renderingService = (RenderingService) ExoContainerContext.getCurrentContainer()
.getComponentInstanceOfType(RenderingService.class);
Execution ec = ((RenderingServiceImpl) renderingService).getExecution();
if (ec.getContext() == null) {
ec.setContext(new ExecutionContext());
}
WikiContext wikiContext = createWikiContext(wikiPortlet);
ec.getContext().setProperty(WikiContext.WIKICONTEXT, wikiContext);
return wikiContext;
}
public static void feedDataForWYSIWYGEditor(UIWikiPageEditForm pageEditForm, String markup) throws Exception {
UIWikiPortlet wikiPortlet = pageEditForm.getAncestorOfType(UIWikiPortlet.class);
UIWikiRichTextArea richTextArea = pageEditForm.getChild(UIWikiRichTextArea.class);
RenderingService renderingService = (RenderingService) PortalContainer.getComponent(RenderingService.class);
HttpSession session = Util.getPortalRequestContext().getRequest().getSession(false);
UIFormTextAreaInput markupInput = pageEditForm.getUIFormTextAreaInput(UIWikiPageEditForm.FIELD_CONTENT);
String markupSyntax = pageEditForm.getUIFormSelectBox(UIWikiPageEditForm.FIELD_SYNTAX).getValue();
WikiContext wikiContext= Utils.setUpWikiContext(wikiPortlet);
if (markup == null) {
markup = (markupInput.getValue() == null) ? "" : markupInput.getValue();
}
String xhtmlContent = renderingService.render(markup, markupSyntax, Syntax.ANNOTATED_XHTML_1_0.toIdString(), false);
richTextArea.getUIFormTextAreaInput().setValue(xhtmlContent);
session.setAttribute(UIWikiRichTextArea.SESSION_KEY, xhtmlContent);
session.setAttribute(UIWikiRichTextArea.WIKI_CONTEXT, wikiContext);
SessionManager sessionManager = (SessionManager) RootContainer.getComponent(SessionManager.class);
sessionManager.addSessionContext(session.getId(), Utils.createWikiContext(wikiPortlet));
}
public static Page isRenderFullHelpPage() throws Exception {
WikiPageParams pageParams = Utils.getCurrentWikiPageParams();
String helpaction = pageParams.getParameter(WikiContext.ACTION);
String syntaxId = pageParams.getParameter("page");
if (helpaction!=null&&syntaxId != null&&helpaction.equals("help") ) {
WikiService wservice = (WikiService) PortalContainer.getComponent(WikiService.class);
PageImpl syntaxPage = wservice.getHelpSyntaxPage(syntaxId.replace("SLASH", "/").replace("DOT", "."));
if (syntaxPage!=null)
{
PageImpl fullHelpPage= (PageImpl) syntaxPage.getChildPages().values().iterator().next();
return fullHelpPage;
}
}
return null;
}
public static String getCurrentWikiPagePath() throws Exception {
return TreeUtils.getPathFromPageParams(getCurrentWikiPageParams());
}
public static Preferences getCurrentPreferences() throws Exception {
WikiImpl currentWiki = (WikiImpl) getCurrentWiki();
return currentWiki.getPreferences();
}
public static WikiContext createWikiContext(UIWikiPortlet wikiPortlet) throws Exception {
PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
UIFormSelectBox syntaxBox = wikiPortlet.findComponentById(UIWikiPageEditForm.FIELD_SYNTAX);
UIPortal uiPortal = Util.getUIPortal();
String requestURL = portalRequestContext.getRequest().getRequestURL().toString();
String portalURI = portalRequestContext.getPortalURI();
String domainURL = requestURL.substring(0, requestURL.indexOf(portalURI));
String portalURL = domainURL + portalURI;
String pageNodeSelected = uiPortal.getSelectedUserNode().getURI();
String treeRestURL = getCurrentRestURL().concat("/wiki/tree/children/");
WikiContext wikiContext = new WikiContext();
wikiContext.setPortalURL(portalURL);
wikiContext.setTreeRestURI(treeRestURL);
wikiContext.setPageTreeId(IdGenerator.generate());
wikiContext.setRestURI(getCurrentRestURL());
wikiContext.setRedirectURI(wikiPortlet.getRedirectURL());
wikiContext.setPortletURI(pageNodeSelected);
WikiPageParams params = Utils.getCurrentWikiPageParams();
wikiContext.setType(params.getType());
wikiContext.setOwner(params.getOwner());
wikiContext.setSyntax(syntaxBox.getValue());
if (wikiPortlet.getWikiMode() == WikiMode.ADDPAGE) {
String sessionId = Util.getPortalRequestContext().getRequest().getSession(false).getId();
wikiContext.setPageId(sessionId);
} else {
wikiContext.setPageId(params.getPageId());
}
return wikiContext;
}
public static String getCurrentWikiNodeUri() throws Exception {
PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
StringBuilder sb = new StringBuilder(portalRequestContext.getPortalURI());
UIPortal uiPortal = Util.getUIPortal();
String pageNodeSelected = uiPortal.getSelectedUserNode().getURI();
sb.append(pageNodeSelected);
return sb.toString();
}
public static void redirect(WikiPageParams pageParams, WikiMode mode) throws Exception {
redirect(pageParams, mode, null);
}
public static void redirect(WikiPageParams pageParams, WikiMode mode, Map<String, String[]> params) throws Exception {
PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
portalRequestContext.setResponseComplete(true);
portalRequestContext.sendRedirect(createURLWithMode(pageParams, mode, params));
}
public static void ajaxRedirect(Event<? extends UIComponent> event,
WikiPageParams pageParams,
WikiMode mode,
Map<String, String[]> params) throws Exception {
String redirectLink = Utils.createURLWithMode(pageParams, mode, params);
event.getRequestContext().getJavascriptManager().addCustomizedOnLoadScript("ajaxRedirect('"
+ redirectLink + "');");
}
public static String createURLWithMode(WikiPageParams pageParams,
WikiMode mode,
Map<String, String[]> params) throws Exception {
StringBuffer sb = new StringBuffer();
sb.append(getURLFromParams(pageParams));
if (!mode.equals(WikiMode.VIEW)) {
sb.append("#").append(Utils.getActionFromWikiMode(mode));
}
if (params != null) {
Iterator<Entry<String, String[]>> iter = params.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, String[]> entry = iter.next();
sb.append("&");
sb.append(entry.getKey()).append("=").append(entry.getValue()[0]);
}
}
return sb.toString();
}
public static String createFormActionLink(UIComponent uiComponent,
String action,
String beanId) throws Exception {
WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
UIForm form = uiComponent.getAncestorOfType(UIForm.class);
if (form != null) {
String formId = form.getId();
if (context instanceof PortletRequestContext) {
formId = ((PortletRequestContext) context).getWindowId() + "#" + formId;
}
StringBuilder b = new StringBuilder();
b.append("javascript:eXo.wiki.UIForm.submitPageEvent('").append(formId).append("','");
b.append(action).append("','");
b.append("&").append(UIForm.SUBCOMPONENT_ID).append("=").append(uiComponent.getId());
if (beanId != null) {
b.append("&").append(UIComponent.OBJECTID).append("=").append(beanId);
}
b.append("')");
return b.toString();
} else {
return form.event(action, uiComponent.getId(), action);
}
}
public static String getActionFromWikiMode(WikiMode mode) {
switch (mode) {
case EDITPAGE:
return "EditPage";
case ADDPAGE:
return "AddPage";
case DELETEPAGE:
return "DeletePage";
case ADDTEMPLATE:
return "AddTemplate";
case EDITTEMPLATE:
return "EditTemplate";
default:
return "";
}
}
public static String getCurrentRestURL() {
StringBuilder sb = new StringBuilder();
sb.append("/").append(PortalContainer.getCurrentPortalContainerName()).append("/");
sb.append(PortalContainer.getCurrentRestContextName());
return sb.toString();
}
public static boolean hasPermission(String[] permissions) throws Exception {
UserACL userACL = Util.getUIPortalApplication().getApplicationComponent(UserACL.class);
/*// If an user is the super user or in the administration group or has the
// create portal permission then he has all permissions
if (userACL.hasCreatePortalPermission()) {
return true;
}
String expAdminGroup = userACL.getAdminGroups();
if (expAdminGroup != null) {
expAdminGroup = expAdminGroup.startsWith("/") ? expAdminGroup : "/" + expAdminGroup;
if (userACL.isUserInGroup(expAdminGroup)) {
return true;
}
}*/
WikiService wikiService = (WikiService) ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(WikiService.class);
WikiPageParams pageParams = Utils.getCurrentWikiPageParams();
List<PermissionEntry> permissionEntries = wikiService.getWikiPermission(pageParams.getType(), pageParams.getOwner());
ConversationState conversationState = ConversationState.getCurrent();
Identity user = null;
if (conversationState != null) {
user = conversationState.getIdentity();
} else {
user = new Identity(IdentityConstants.ANONIM);
}
List<AccessControlEntry> aces = new ArrayList<AccessControlEntry>();
for (PermissionEntry permissionEntry : permissionEntries) {
Permission[] perms = permissionEntry.getPermissions();
for (Permission perm : perms) {
if (perm.isAllowed()) {
AccessControlEntry ace = new AccessControlEntry(permissionEntry.getId(), perm.getPermissionType().toString());
aces.add(ace);
}
}
}
AccessControlList acl = new AccessControlList(userACL.getSuperUser(), aces);
return org.exoplatform.wiki.utils.Utils.hasPermission(acl, permissions, user);
}
public static WikiMode getModeFromAction(String actionParam) {
String[] params = actionParam.split(WITH);
String name = params[0];
if (name != null) {
try {
WikiMode mode = WikiMode.valueOf(name.toUpperCase());
if (mode != null)
return mode;
} catch (IllegalArgumentException e) {
return null;
}
}
return null;
}
/**
* render macro to XHtml string.
* @param uiComponent - component that contain the macro.
* @param macroName - name of macro
* @param wikiSyntax - wiki syntax referred from {@link Syntax}
* @return String in format {@link Syntax#XHTML_1_0}
*/
public static String renderMacroToXHtml(UIComponent uiComponent, String macroName, String wikiSyntax) {
try {
RenderingService renderingService = (RenderingService) PortalContainer.getComponent(RenderingService.class);
setUpWikiContext(uiComponent.getAncestorOfType(UIWikiPortlet.class));
String content= renderingService.render(macroName,
wikiSyntax,
Syntax.XHTML_1_0.toIdString(),
false);
return content;
} catch (Exception e) {
return "";
}
}
public static void removeWikiContext() throws Exception {
RenderingService renderingService = (RenderingService) PortalContainer.getComponent(RenderingService.class);
Execution ec = ((RenderingServiceImpl) renderingService).getExecution();
if (ec != null) {
ec.removeContext();
}
}
public static List<NTVersion> getCurrentPageRevisions() throws Exception {
PageImpl wikipage = (PageImpl) getCurrentWikiPage();
Iterator<NTVersion> iter = wikipage.getVersionableMixin().getVersionHistory().iterator();
List<NTVersion> versionsList = new ArrayList<NTVersion>();
while (iter.hasNext()) {
NTVersion version = iter.next();
if (!(WikiNodeType.Definition.ROOT_VERSION.equals(version.getName()))) {
versionsList.add(version);
}
}
Collections.sort(versionsList, new VersionNameComparatorDesc());
return versionsList;
}
public static int getLimitUploadSize() {
PortletRequestContext pcontext = (PortletRequestContext) WebuiRequestContext.getCurrentInstance();
PortletPreferences portletPref = pcontext.getRequest().getPreferences();
int limitMB = DEFAULT_VALUE_UPLOAD_PORTAL;
try {
limitMB = Integer.parseInt(portletPref.getValue("uploadFileSizeLimitMB", "").trim());
} catch (Exception e) {
limitMB = 10;
}
return limitMB;
}
}