/* * 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.service.impl; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URI; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collection; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Stack; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilderException; import javax.ws.rs.core.UriInfo; import org.apache.commons.fileupload.DiskFileUpload; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.io.FilenameUtils; import org.exoplatform.common.http.HTTPStatus; import org.exoplatform.commons.utils.MimeTypeResolver; import org.exoplatform.container.ExoContainer; import org.exoplatform.container.ExoContainerContext; import org.exoplatform.container.PortalContainer; import org.exoplatform.ks.common.image.ResizeImageService; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.services.rest.impl.EnvironmentContext; import org.exoplatform.services.rest.resource.ResourceContainer; import org.exoplatform.services.security.ConversationState; 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.wiki.AttachmentImpl; import org.exoplatform.wiki.mow.core.api.wiki.PageImpl; import org.exoplatform.wiki.rendering.RenderingService; import org.exoplatform.wiki.rendering.impl.RenderingServiceImpl; import org.exoplatform.wiki.service.Relations; import org.exoplatform.wiki.service.WikiContext; import org.exoplatform.wiki.service.WikiPageParams; import org.exoplatform.wiki.service.WikiResource; import org.exoplatform.wiki.service.WikiRestService; import org.exoplatform.wiki.service.WikiService; import org.exoplatform.wiki.service.related.JsonRelatedData; import org.exoplatform.wiki.service.related.RelatedUtil; import org.exoplatform.wiki.service.rest.model.Attachment; import org.exoplatform.wiki.service.rest.model.Attachments; import org.exoplatform.wiki.service.rest.model.Link; import org.exoplatform.wiki.service.rest.model.ObjectFactory; import org.exoplatform.wiki.service.rest.model.PageSummary; import org.exoplatform.wiki.service.rest.model.Pages; import org.exoplatform.wiki.service.rest.model.Space; import org.exoplatform.wiki.service.rest.model.Spaces; import org.exoplatform.wiki.service.search.TitleSearchResult; import org.exoplatform.wiki.service.search.WikiSearchData; import org.exoplatform.wiki.tree.JsonNodeData; import org.exoplatform.wiki.tree.TreeNode; import org.exoplatform.wiki.tree.TreeNode.TREETYPE; import org.exoplatform.wiki.tree.WikiTreeNode; import org.exoplatform.wiki.tree.utils.TreeUtils; import org.exoplatform.wiki.utils.Utils; 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 * Jun 20, 2010 */ @Path("/wiki") public class WikiRestServiceImpl implements WikiRestService, ResourceContainer { private final WikiService wikiService; private final RenderingService renderingService; private static Log log = ExoLogger.getLogger("wiki:WikiRestService"); private final CacheControl cc; private ObjectFactory objectFactory = new ObjectFactory(); public WikiRestServiceImpl(WikiService wikiService, RenderingService renderingService) { this.wikiService = wikiService; this.renderingService = renderingService; cc = new CacheControl(); cc.setNoCache(true); cc.setNoStore(true); } /** * {@inheritDoc} */ @POST @Path("/content/") @Produces(MediaType.TEXT_HTML) public Response getWikiPageContent(@QueryParam("sessionKey") String sessionKey, @QueryParam("wikiContext") String wikiContextKey, @QueryParam("markup") boolean isMarkup, @FormParam("html") String data) { EnvironmentContext env = EnvironmentContext.getCurrent(); WikiContext wikiContext = new WikiContext(); String currentSyntax = Syntax.XWIKI_2_0.toIdString(); HttpServletRequest request = (HttpServletRequest) env.get(HttpServletRequest.class); try { if (data == null) { if (sessionKey != null && sessionKey.length() > 0) { data = (String) request.getSession().getAttribute(sessionKey); } } if (wikiContextKey != null && wikiContextKey.length() > 0) { wikiContext = (WikiContext) request.getSession().getAttribute(wikiContextKey); currentSyntax = wikiContext.getSyntax(); } Execution ec = ((RenderingServiceImpl) renderingService).getExecution(); if (ec.getContext() == null) { ec.setContext(new ExecutionContext()); } ec.getContext().setProperty(WikiContext.WIKICONTEXT, wikiContext); ServletContext wikiServletContext = PortalContainer.getInstance() .getPortalContext() .getContext("/wiki"); InputStream is = wikiServletContext.getResourceAsStream("/templates/wiki/webui/xwiki/wysiwyginput.html"); byte[] b = new byte[is.available()]; is.read(b); is.close(); data = renderingService.render(data, Syntax.XHTML_1_0.toIdString(), currentSyntax, false); data = renderingService.render(data, currentSyntax, Syntax.ANNOTATED_XHTML_1_0.toIdString(), false); data = new String(b).replace("$content", data); } catch (Exception e) { log.error(e.getMessage(), e); return Response.serverError().entity(e.getMessage()).cacheControl(cc).build(); } return Response.ok(data, MediaType.TEXT_HTML).cacheControl(cc).build(); } @POST @Path("/upload/{wikiType}/{wikiOwner:.+}/{pageId}/") public Response upload(@PathParam("wikiType") String wikiType, @PathParam("wikiOwner") String wikiOwner, @PathParam("pageId") String pageId) { EnvironmentContext env = EnvironmentContext.getCurrent(); HttpServletRequest req = (HttpServletRequest) env.get(HttpServletRequest.class); boolean isMultipart = FileUploadBase.isMultipartContent(req); if (isMultipart) { DiskFileUpload upload = new DiskFileUpload(); // Parse the request try { List<FileItem> items = upload.parseRequest(req); for (FileItem fileItem : items) { InputStream inputStream = fileItem.getInputStream(); byte[] imageBytes; if (inputStream != null) { imageBytes = new byte[inputStream.available()]; inputStream.read(imageBytes); } else { imageBytes = null; } String fileName = fileItem.getName(); String fileType = fileItem.getContentType(); if (fileName != null) { // It's necessary because IE posts full path of uploaded files fileName = FilenameUtils.getName(fileName); fileType = FilenameUtils.getExtension(fileName); } String mimeType = new MimeTypeResolver().getMimeType(fileName); WikiResource attachfile = new WikiResource(mimeType, "UTF-8", imageBytes); attachfile.setName(fileName); if (attachfile != null) { WikiService wikiService = (WikiService) PortalContainer.getComponent(WikiService.class); Page page = wikiService.getExsitedOrNewDraftPageById(wikiType, wikiOwner, pageId); if (page != null) { AttachmentImpl att = ((PageImpl) page).createAttachment(attachfile.getName(), attachfile); ConversationState conversationState = ConversationState.getCurrent(); String creator = null; if (conversationState != null && conversationState.getIdentity() != null) { creator = conversationState.getIdentity().getUserId(); } att.setCreator(creator); Utils.reparePermissions(att); } } } } catch (Exception e) { log.error(e.getMessage(), e); return Response.status(HTTPStatus.BAD_REQUEST).entity(e.getMessage()).build(); } } return Response.ok().build(); } @GET @Path("/tree/{type}") @Produces(MediaType.APPLICATION_JSON) public Response getTreeData(@PathParam("type") String type, @QueryParam(TreeNode.PATH) String path, @QueryParam(TreeNode.CURRENT_PATH) String currentPath, @QueryParam(TreeNode.SHOW_EXCERPT) Boolean showExcerpt, @QueryParam(TreeNode.DEPTH) String depth) { try { List<JsonNodeData> responseData = new ArrayList<JsonNodeData>(); HashMap<String, Object> context = new HashMap<String, Object>(); path = URLDecoder.decode(path, "utf-8"); if (currentPath != null){ currentPath = URLDecoder.decode(currentPath, "utf-8"); context.put(TreeNode.CURRENT_PATH, currentPath); } context.put(TreeNode.SHOW_EXCERPT, showExcerpt); WikiPageParams pageParam = TreeUtils.getPageParamsFromPath(path); if (type.equalsIgnoreCase(TREETYPE.ALL.toString())) { PageImpl page = (PageImpl) wikiService.getPageById(pageParam.getType(), pageParam.getOwner(), pageParam.getPageId()); Stack<WikiPageParams> stk = Utils.getStackParams(page); context.put(TreeNode.STACK_PARAMS, stk); responseData = getJsonTree(pageParam, context); } else if (type.equalsIgnoreCase(TREETYPE.CHILDREN.toString())) { // Get children only if (depth == null) depth = "1"; context.put(TreeNode.DEPTH, depth); responseData = getJsonDescendants(pageParam, context); } return Response.ok(new BeanToJsons(responseData), MediaType.APPLICATION_JSON) .cacheControl(cc) .build(); } catch (Exception e) { log.error("Failed for get tree data by rest service.", e); return Response.serverError().entity(e.getMessage()).cacheControl(cc).build(); } } @GET @Path("/related/") @Produces(MediaType.APPLICATION_JSON) public Response getRelated(@QueryParam(TreeNode.PATH) String path) { if (path == null) { return Response.status(Status.NOT_FOUND).build(); } try { WikiPageParams params = TreeUtils.getPageParamsFromPath(path); PageImpl page = (PageImpl) wikiService.getPageById(params.getType(), params.getOwner(), params.getPageId()); List<PageImpl> relatedPages = page.getRelatedPages(); List<JsonRelatedData> relatedData = RelatedUtil.pageImplToJson(relatedPages); return Response.ok(new BeanToJsons<JsonRelatedData>(relatedData)).cacheControl(cc).build(); } catch (Exception e) { if (log.isErrorEnabled()) log.error(String.format("can not get related pages of [%s]", path), e); return Response.serverError().cacheControl(cc).build(); } } @GET @Path("/{wikiType}/spaces") @Produces("application/xml") public Spaces getSpaces(@Context UriInfo uriInfo, @PathParam("wikiType") String wikiType, @QueryParam("start") Integer start, @QueryParam("number") Integer number) { Spaces spaces = objectFactory.createSpaces(); List<String> spaceNames = new ArrayList<String>(); Collection<Wiki> wikis = Utils.getWikisByType(WikiType.valueOf(wikiType.toUpperCase())); for (Wiki wiki : wikis) { spaceNames.add(wiki.getOwner()); } for (String spaceName : spaceNames) { try { Page page = wikiService.getPageById(wikiType, spaceName, WikiNodeType.Definition.WIKI_HOME_NAME); spaces.getSpaces().add(createSpace(objectFactory, uriInfo.getBaseUri(), wikiType, spaceName, page)); } catch (Exception e) { log.error(e.getMessage(), e); } } return spaces; } @GET @Path("/{wikiType}/spaces/{wikiOwner:.+}/") @Produces("application/xml") public Space getSpace(@Context UriInfo uriInfo, @PathParam("wikiType") String wikiType, @PathParam("wikiOwner") String wikiOwner) { Page page; try { page = wikiService.getPageById(wikiType, wikiOwner, WikiNodeType.Definition.WIKI_HOME_NAME); } catch (Exception e) { log.error(e.getMessage(), e); return objectFactory.createSpace(); } return createSpace(objectFactory, uriInfo.getBaseUri(), wikiType, wikiOwner, page); } @GET @Path("/{wikiType}/spaces/{wikiOwner:.+}/pages") @Produces("application/xml") public Pages getPages(@Context UriInfo uriInfo, @PathParam("wikiType") String wikiType, @PathParam("wikiOwner") String wikiOwner, @QueryParam("start") Integer start, @QueryParam("number") Integer number, @QueryParam("parentId") String parentFilterExpression) { Pages pages = objectFactory.createPages(); PageImpl page = null; boolean isWikiHome = true; try { String parentId = WikiNodeType.Definition.WIKI_HOME_NAME; if (parentFilterExpression != null && parentFilterExpression.length() > 0 && !parentFilterExpression.startsWith("^(?!")) { parentId = parentFilterExpression; if (parentId.indexOf(".") >= 0) { parentId = parentId.substring(parentId.indexOf(".") + 1); } isWikiHome = false; } page = (PageImpl) wikiService.getPageById(wikiType, wikiOwner, parentId); if (isWikiHome) { pages.getPageSummaries().add(createPageSummary(objectFactory, uriInfo.getBaseUri(), page)); } else { for (PageImpl childPage : page.getChildPages().values()) { pages.getPageSummaries().add(createPageSummary(objectFactory, uriInfo.getBaseUri(), childPage)); } } } catch (Exception e) { log.error("Can't get children pages of:" + parentFilterExpression, e); } return pages; } @GET @Path("/{wikiType}/spaces/{wikiOwner:.+}/pages/{pageId}") @Produces("application/xml") public org.exoplatform.wiki.service.rest.model.Page getPage(@Context UriInfo uriInfo, @PathParam("wikiType") String wikiType, @PathParam("wikiOwner") String wikiOwner, @PathParam("pageId") String pageId) { PageImpl page; try { page = (PageImpl) wikiService.getPageById(wikiType, wikiOwner, pageId); if (page != null) { return createPage(objectFactory, uriInfo.getBaseUri(), uriInfo.getAbsolutePath(), page); } } catch (Exception e) { log.error(e.getMessage(), e); } return objectFactory.createPage(); } @GET @Path("/{wikiType}/spaces/{wikiOwner:.+}/pages/{pageId}/attachments") @Produces("application/xml") public Attachments getAttachments(@Context UriInfo uriInfo, @PathParam("wikiType") String wikiType, @PathParam("wikiOwner") String wikiOwner, @PathParam("pageId") String pageId, @QueryParam("start") Integer start, @QueryParam("number") Integer number) { Attachments attachments = objectFactory.createAttachments(); PageImpl page; try { page = (PageImpl) wikiService.getPageById(wikiType, wikiOwner, pageId); Collection<AttachmentImpl> pageAttachments = page.getAttachmentsExcludeContent(); for (AttachmentImpl pageAttachment : pageAttachments) { attachments.getAttachments().add(createAttachment(objectFactory, uriInfo.getBaseUri(), pageAttachment, "attachment", "attachment")); } } catch (Exception e) { log.error(e.getMessage(), e); } return attachments; } @GET @Path("contextsearch/{keyword}") @Produces(MediaType.APPLICATION_JSON) public Response searchData(@PathParam("keyword") String keyword) throws Exception { try { WikiSearchData data = new WikiSearchData(null, keyword.toLowerCase(), null, null, null); List<TitleSearchResult> result = wikiService.searchDataByTitle(data); return Response.ok(new BeanToJsons(result), MediaType.APPLICATION_JSON) .cacheControl(cc) .build(); } catch (Exception e) { return Response.status(HTTPStatus.INTERNAL_ERROR).cacheControl(cc).build(); } } @GET @Path("/images/{wikiType}/{wikiOwner}/{pageId}/{imageId}") @Produces("image") public Response getImage(@Context UriInfo uriInfo, @PathParam("wikiType") String wikiType, @PathParam("wikiOwner") String wikiOwner, @PathParam("pageId") String pageId, @PathParam("imageId") String imageId, @QueryParam("width") Integer width) { InputStream result = null; try { ResizeImageService resizeImgService = (ResizeImageService) ExoContainerContext.getCurrentContainer() .getComponentInstanceOfType(ResizeImageService.class); PageImpl page = (PageImpl) wikiService.getPageById(wikiType, wikiOwner, pageId); AttachmentImpl att = page.getAttachment(imageId); ByteArrayInputStream bis = new ByteArrayInputStream(att.getContentResource().getData()); if (width != null) { result = resizeImgService.resizeImageByWidth(imageId, bis, width); } else { result = bis; } return Response.ok(result, "image").cacheControl(cc).build(); } catch (Exception e) { if (log.isDebugEnabled()) log.debug(String.format("Can't get image name: %s of page %s", imageId, pageId), e); return Response.status(HTTPStatus.INTERNAL_ERROR).cacheControl(cc).build(); } } public Space createSpace(ObjectFactory objectFactory, URI baseUri, String wikiName, String spaceName, Page home) { Space space = objectFactory.createSpace(); space.setId(String.format("%s:%s", wikiName, spaceName)); space.setWiki(wikiName); space.setName(spaceName); if (home != null) { space.setHome("home"); space.setXwikiRelativeUrl("home"); space.setXwikiAbsoluteUrl("home"); } String pagesUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages") .build(wikiName, spaceName) .toString(); Link pagesLink = objectFactory.createLink(); pagesLink.setHref(pagesUri); pagesLink.setRel(Relations.PAGES); space.getLinks().add(pagesLink); if (home != null) { String homeUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}") .build(wikiName, spaceName, home.getName()) .toString(); Link homeLink = objectFactory.createLink(); homeLink.setHref(homeUri); homeLink.setRel(Relations.HOME); space.getLinks().add(homeLink); } String searchUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/search") .build(wikiName, spaceName) .toString(); Link searchLink = objectFactory.createLink(); searchLink.setHref(searchUri); searchLink.setRel(Relations.SEARCH); space.getLinks().add(searchLink); return space; } public org.exoplatform.wiki.service.rest.model.Page createPage(ObjectFactory objectFactory, URI baseUri, URI self, PageImpl doc) throws Exception { org.exoplatform.wiki.service.rest.model.Page page = objectFactory.createPage(); fillPageSummary(page, objectFactory, baseUri, doc); page.setVersion("current"); page.setMajorVersion(1); page.setMinorVersion(0); page.setLanguage(doc.getSyntax()); page.setCreator(doc.getOwner()); GregorianCalendar calendar = new GregorianCalendar(); page.setCreated(calendar); page.setModifier(doc.getAuthor()); calendar = new GregorianCalendar(); calendar.setTime(doc.getUpdatedDate()); page.setModified(calendar); page.setContent(doc.getContent().getText()); if (self != null) { Link pageLink = objectFactory.createLink(); pageLink.setHref(self.toString()); pageLink.setRel(Relations.SELF); page.getLinks().add(pageLink); } return page; } public PageSummary createPageSummary(ObjectFactory objectFactory, URI baseUri, PageImpl doc) throws IllegalArgumentException, UriBuilderException, Exception { PageSummary pageSummary = objectFactory.createPageSummary(); fillPageSummary(pageSummary, objectFactory, baseUri, doc); String wikiName = doc.getWiki().getType(); String spaceName = doc.getWiki().getOwner(); String pageUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}") .build(wikiName, spaceName, doc.getName()) .toString(); Link pageLink = objectFactory.createLink(); pageLink.setHref(pageUri); pageLink.setRel(Relations.PAGE); pageSummary.getLinks().add(pageLink); return pageSummary; } public Attachment createAttachment(ObjectFactory objectFactory, URI baseUri, AttachmentImpl pageAttachment, String xwikiRelativeUrl, String xwikiAbsoluteUrl) throws Exception { Attachment attachment = objectFactory.createAttachment(); fillAttachment(attachment, objectFactory, baseUri, pageAttachment, xwikiRelativeUrl, xwikiAbsoluteUrl); PageImpl page = pageAttachment.getParentPage(); String attachmentUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}/attachments/{attachmentName}") .build(page.getWiki().getType(), page.getWiki().getOwner(), page.getName(), pageAttachment.getName()) .toString(); Link attachmentLink = objectFactory.createLink(); attachmentLink.setHref(attachmentUri); attachmentLink.setRel(Relations.ATTACHMENT_DATA); attachment.getLinks().add(attachmentLink); return attachment; } private List<JsonNodeData> getJsonTree(WikiPageParams params,HashMap<String, Object> context) throws Exception { List<JsonNodeData> responseData = new ArrayList<JsonNodeData>(); String currentPath = (String) context.get(TreeNode.CURRENT_PATH); Wiki wiki = Utils.getWiki(params); WikiTreeNode wikiNode = new WikiTreeNode(wiki); wikiNode.pushDescendants(context); responseData = TreeUtils.tranformToJson(wikiNode, context); return responseData; } private List<JsonNodeData> getJsonDescendants(WikiPageParams params, HashMap<String, Object> context) throws Exception { TreeNode treeNode = TreeUtils.getDescendants(params, context); return TreeUtils.tranformToJson(treeNode, context); } private static void fillPageSummary(PageSummary pageSummary, ObjectFactory objectFactory, URI baseUri, PageImpl doc) throws IllegalArgumentException, UriBuilderException, Exception { String wikiType = doc.getWiki().getType(); pageSummary.setWiki(wikiType); pageSummary.setFullName(doc.getTitle()); pageSummary.setId(wikiType + ":" + doc.getWiki().getOwner() + "." + doc.getName()); pageSummary.setSpace(doc.getWiki().getOwner()); pageSummary.setName(doc.getName()); pageSummary.setTitle(doc.getTitle()); pageSummary.setXwikiRelativeUrl("http://localhost:8080/ksdemo/rest-ksdemo/wiki/portal/spaces/classic/pages/WikiHome"); pageSummary.setXwikiAbsoluteUrl("http://localhost:8080/ksdemo/rest-ksdemo/wiki/portal/spaces/classic/pages/WikiHome"); pageSummary.setTranslations(objectFactory.createTranslations()); pageSummary.setSyntax(doc.getSyntax()); PageImpl parent = doc.getParentPage(); // parentId must not be set if the parent document does not exist. if (parent != null) { pageSummary.setParent(parent.getName()); pageSummary.setParentId(parent.getName()); } else { pageSummary.setParent(""); pageSummary.setParentId(""); } String spaceUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}") .build(wikiType, doc.getWiki().getOwner()) .toString(); Link spaceLink = objectFactory.createLink(); spaceLink.setHref(spaceUri); spaceLink.setRel(Relations.SPACE); pageSummary.getLinks().add(spaceLink); if (parent != null) { String parentUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}") .build(parent.getWiki().getType(), parent.getWiki().getOwner(), parent.getName()) .toString(); Link parentLink = objectFactory.createLink(); parentLink.setHref(parentUri); parentLink.setRel(Relations.PARENT); pageSummary.getLinks().add(parentLink); } if (!doc.getChildPages().isEmpty()) { String pageChildrenUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}/children") .build(wikiType, doc.getWiki().getOwner(), doc.getName()) .toString(); Link pageChildrenLink = objectFactory.createLink(); pageChildrenLink.setHref(pageChildrenUri); pageChildrenLink.setRel(Relations.CHILDREN); pageSummary.getLinks().add(pageChildrenLink); } if (!doc.getAttachmentsExcludeContent().isEmpty()) { String attachmentsUri; attachmentsUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}/attachments") .build(wikiType, doc.getWiki().getOwner(), doc.getName()) .toString(); Link attachmentsLink = objectFactory.createLink(); attachmentsLink.setHref(attachmentsUri); attachmentsLink.setRel(Relations.ATTACHMENTS); pageSummary.getLinks().add(attachmentsLink); } } private void fillAttachment(Attachment attachment, ObjectFactory objectFactory, URI baseUri, AttachmentImpl pageAttachment, String xwikiRelativeUrl, String xwikiAbsoluteUrl) throws Exception { PageImpl page = pageAttachment.getParentPage(); attachment.setId(String.format("%s@%s", page.getName(), pageAttachment.getName())); attachment.setName(pageAttachment.getName()); attachment.setSize((int) pageAttachment.getWeightInBytes()); attachment.setVersion("current"); attachment.setPageId(page.getName()); attachment.setPageVersion("current"); attachment.setMimeType(pageAttachment.getContentResource().getMimeType()); attachment.setAuthor(pageAttachment.getCreator()); GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(pageAttachment.getCreated()); attachment.setDate(calendar); attachment.setXwikiRelativeUrl(xwikiRelativeUrl); attachment.setXwikiAbsoluteUrl(xwikiAbsoluteUrl); String pageUri = UriBuilder.fromUri(baseUri) .path("/wiki/{wikiName}/spaces/{spaceName}/pages/{pageName}") .build(page.getWiki().getType(), page.getWiki().getOwner(), page.getName()) .toString(); Link pageLink = objectFactory.createLink(); pageLink.setHref(pageUri); pageLink.setRel(Relations.PAGE); attachment.getLinks().add(pageLink); } @GET @Path("/help/{syntaxId}") @Produces(MediaType.TEXT_HTML) /** * Return the help syntax page. * The syntax id have to replaced all special characters: * Character '/' have to replace to "SLASH" * Character '.' have to replace to "DOT" * * Sample: * "confluence/1.0" will be replaced to "confluenceSLASH1DOT0" * * @param syntaxId The id of syntax to show in help page * @return The response that contains help page */ public Response getHelpSyntaxPage(@PathParam("syntaxId") String syntaxId) { CacheControl cacheControl = new CacheControl(); syntaxId = syntaxId.replace(Utils.SLASH, "/").replace(Utils.DOT, "."); try { PageImpl page = wikiService.getHelpSyntaxPage(syntaxId); if (page == null) { return Response.status(HTTPStatus.NOT_FOUND).cacheControl(cc).build(); } Page fullHelpPage = (Page) page.getChildPages().values().iterator().next(); // Get help page body ExoContainer container = ExoContainerContext.getCurrentContainer(); RenderingService renderingService = (RenderingService) container.getComponentInstanceOfType(RenderingService.class); String body = renderingService.render(fullHelpPage.getContent().getText(), fullHelpPage.getSyntax(), Syntax.XHTML_1_0.toIdString(), false); // Create javascript to load css StringBuilder script = new StringBuilder("<script type=\"text/javascript\">") .append("var local = String(window.location);") .append("var i = local.indexOf('/', local.indexOf('//') + 2);") .append("local = (i <= 0) ? local : local.substring(0, i);") .append("local = local + '/wiki/skin/DefaultSkin/webui/Stylesheet.css';") .append("document.write('<link rel=\"stylesheet\" type=\"text/css\" href=\"' + local + '\">');") .append("</script>"); // Create help html page StringBuilder htmlOutput = new StringBuilder(); htmlOutput.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">") .append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">") .append("<head id=\"head\">") .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>") .append(script) .append("</head>") .append("<body>") .append("<div class=\"UIWikiPageContentArea\">") .append(body) .append("</div>") .append("</body>") .append("</html>"); return Response.ok(htmlOutput.toString(), MediaType.TEXT_HTML).cacheControl(cacheControl).build(); } catch (Exception e) { if (log.isWarnEnabled()) { log.warn("An exception happens when getHelpSyntaxPage", e); } return Response.status(HTTPStatus.INTERNAL_ERROR).cacheControl(cc).build(); } } }