001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.apidoc.browse; 020 021import java.io.Serializable; 022import java.io.UnsupportedEncodingException; 023import java.net.URLDecoder; 024import java.net.URLEncoder; 025import java.util.ArrayList; 026import java.util.List; 027import java.util.Map; 028 029import javax.ws.rs.FormParam; 030import javax.ws.rs.GET; 031import javax.ws.rs.POST; 032import javax.ws.rs.Path; 033import javax.ws.rs.PathParam; 034import javax.ws.rs.Produces; 035import javax.ws.rs.QueryParam; 036 037import org.apache.commons.logging.Log; 038import org.apache.commons.logging.LogFactory; 039import org.nuxeo.apidoc.api.AssociatedDocuments; 040import org.nuxeo.apidoc.api.DocumentationItem; 041import org.nuxeo.apidoc.api.NuxeoArtifact; 042import org.nuxeo.apidoc.doc.SimpleDocumentationItem; 043import org.nuxeo.apidoc.documentation.DocumentationService; 044import org.nuxeo.apidoc.snapshot.SnapshotManager; 045import org.nuxeo.ecm.core.api.Blobs; 046import org.nuxeo.ecm.core.api.CoreSession; 047import org.nuxeo.ecm.core.api.DocumentModel; 048import org.nuxeo.ecm.core.api.IdRef; 049import org.nuxeo.ecm.webengine.model.Module; 050import org.nuxeo.ecm.webengine.model.Template; 051import org.nuxeo.ecm.webengine.model.exceptions.WebSecurityException; 052import org.nuxeo.ecm.webengine.model.impl.DefaultObject; 053import org.nuxeo.runtime.api.Framework; 054 055public abstract class NuxeoArtifactWebObject extends DefaultObject { 056 057 private static final Log log = LogFactory.getLog(NuxeoArtifactWebObject.class); 058 059 protected String nxArtifactId; 060 061 @Override 062 protected void initialize(Object... args) { 063 nxArtifactId = (String) args[0]; 064 } 065 066 protected String getNxArtifactId() { 067 return nxArtifactId; 068 } 069 070 protected SnapshotManager getSnapshotManager() { 071 return Framework.getService(SnapshotManager.class); 072 } 073 074 @Override 075 public Template getView(String viewId) { 076 return super.getView(viewId).arg(Distribution.DIST_ID, getDistributionId()).arg("onArtifact", true); 077 } 078 079 public abstract NuxeoArtifact getNxArtifact(); 080 081 protected abstract Object doGet(); 082 083 protected String getDistributionId() { 084 return (String) ctx.getProperty(Distribution.DIST_ID); 085 } 086 087 public AssociatedDocuments getAssociatedDocuments() { 088 NuxeoArtifact nxItem = getNxArtifact(); 089 return nxItem.getAssociatedDocuments(ctx.getCoreSession()); 090 } 091 092 @POST 093 @Produces("text/html") 094 @Path("updateDocumentation") 095 public Object doUpdateDocumentation(DocumentationItem docItem) { 096 if (!SecurityHelper.canEditDocumentation(getContext())) { 097 throw new WebSecurityException("You are not allowed to do this operation"); 098 } 099 100 DocumentationService ds = Framework.getService(DocumentationService.class); 101 102 ds.updateDocumentationItem(ctx.getCoreSession(), docItem); 103 return redirect(getDocUrl()); 104 } 105 106 protected String getDocUrl() { 107 String path = getPath() + "/doc"; 108 // //TODO encode path segments if needed 109 return path; 110 } 111 112 @Deprecated 113 protected String computeUrl(String suffix) throws UnsupportedEncodingException { 114 String targetUrl = ctx.getUrlPath(); 115 targetUrl = URLDecoder.decode(targetUrl, "ISO-8859-1"); 116 targetUrl = targetUrl.replace(ctx.getBasePath(), ""); 117 targetUrl = targetUrl.replace(suffix, "/doc"); 118 targetUrl = URLEncoder.encode(targetUrl, "ISO-8859-1"); 119 return targetUrl; 120 } 121 122 @POST 123 @Produces("text/html") 124 @Path("createDocumentation") 125 public Object doCreateDocumentation(DocumentationItem docItem) { 126 if (!SecurityHelper.canEditDocumentation(getContext())) { 127 throw new WebSecurityException("You are not allowed to do this operation"); 128 } 129 130 DocumentationService ds = Framework.getService(DocumentationService.class); 131 ds.createDocumentationItem(ctx.getCoreSession(), getNxArtifact(), docItem.getTitle(), docItem.getContent(), 132 docItem.getType(), docItem.getApplicableVersion(), docItem.isApproved(), docItem.getRenderingType()); 133 return redirect(getDocUrl()); 134 } 135 136 @POST 137 @Produces("text/html") 138 @Path("deleteDocumentation") 139 public Object doDeleteDocumentation(@FormParam("uuid") String uuid) { 140 if (!SecurityHelper.canEditDocumentation(getContext())) { 141 throw new WebSecurityException("You are not allowed to do this operation"); 142 } 143 DocumentationService ds = Framework.getService(DocumentationService.class); 144 ds.deleteDocumentationItem(ctx.getCoreSession(), uuid); 145 return redirect(getDocUrl()); 146 } 147 148 @GET 149 @Produces("text/html") 150 public Object doViewDefault() { 151 NuxeoArtifact nxItem = getNxArtifact(); 152 AssociatedDocuments docs = nxItem.getAssociatedDocuments(ctx.getCoreSession()); 153 return getView("default").arg("nxItem", nxItem).arg("docs", docs).arg("selectedTab", "defView"); 154 } 155 156 @GET 157 @Produces("text/html") 158 @Path("doc") 159 public Object doViewDoc() { 160 NuxeoArtifact nxItem = getNxArtifact(); 161 AssociatedDocuments docs = nxItem.getAssociatedDocuments(ctx.getCoreSession()); 162 return getView("../documentation").arg("nxItem", nxItem).arg("docs", docs).arg("selectedTab", "docView"); 163 } 164 165 @GET 166 @Produces("text/html") 167 @Path("aggregated") 168 public Object doViewAggregated() { 169 NuxeoArtifact nxItem = getNxArtifact(); 170 AssociatedDocuments docs = nxItem.getAssociatedDocuments(ctx.getCoreSession()); 171 return getView("aggregated").arg("nxItem", nxItem).arg("docs", docs).arg("selectedTab", "aggView"); 172 } 173 174 @GET 175 @Produces("text/html") 176 @Path("createForm") 177 public Object doAddDoc(@QueryParam("inline") Boolean inline, @QueryParam("type") String type) { 178 NuxeoArtifact nxItem = getNxArtifact(); 179 List<String> versions = getSnapshotManager().getAvailableVersions(ctx.getCoreSession(), nxItem); 180 DocumentationItem docItem = new SimpleDocumentationItem(nxItem); 181 String targetView = "../docForm"; 182 if (inline != null && inline.equals(Boolean.TRUE)) { 183 targetView = "../../docItemForm"; 184 } 185 return getView(targetView).arg("nxItem", nxItem).arg("mode", "create").arg("docItem", docItem).arg("versions", 186 versions).arg("selectedTab", "docView").arg("preselectedType", type); 187 } 188 189 @GET 190 @Produces("text/html") 191 @Path("editForm/{uuid}") 192 public Object doEditDoc(@PathParam("uuid") String uuid) { 193 NuxeoArtifact nxItem = getNxArtifact(); 194 List<String> versions = getSnapshotManager().getAvailableVersions(ctx.getCoreSession(), nxItem); 195 DocumentModel existingDoc = ctx.getCoreSession().getDocument(new IdRef(uuid)); 196 DocumentationItem docItem = existingDoc.getAdapter(DocumentationItem.class); 197 return getView("../docForm").arg("nxItem", nxItem).arg("mode", "edit").arg("docItem", docItem).arg("versions", 198 versions).arg("selectedTab", "docView"); 199 } 200 201 @GET 202 @Produces("text/plain") 203 @Path("quickEdit/{editId}") 204 public Object quickEdit(@PathParam("editId") String editId) { 205 206 if (editId == null || editId.startsWith("placeholder_")) { 207 return ""; 208 } 209 210 DocumentModel doc = getContext().getCoreSession().getDocument(new IdRef(editId)); 211 DocumentationItem item = doc.getAdapter(DocumentationItem.class); 212 213 return item.getContent(); 214 } 215 216 @POST 217 @Produces("text/plain") 218 @Path("quickEdit/{editId}") 219 public Object quickEditSave(@PathParam("editId") String editId) { 220 221 String title = getContext().getForm().getString("title"); 222 String content = getContext().getForm().getString("content"); 223 String type = getContext().getForm().getString("type"); 224 if (type == null || type.trim().length() == 0) { 225 type = "description"; 226 } 227 228 String renderingType = "wiki"; 229 if (content.contains("<ul>") || content.contains("<p>") || content.contains("<br/>")) { 230 renderingType = "html"; 231 } 232 233 List<String> applicableVersions = new ArrayList<String>(); 234 applicableVersions.add(getSnapshotManager().getSnapshot(getDistributionId(), getContext().getCoreSession()).getVersion()); // XXX 235 // !!! 236 DocumentationService ds = Framework.getService(DocumentationService.class); 237 if (editId == null || editId.startsWith("placeholder_")) { 238 ds.createDocumentationItem(getContext().getCoreSession(), getNxArtifact(), title, content, type, 239 applicableVersions, false, renderingType); 240 } else { 241 DocumentModel doc = getContext().getCoreSession().getDocument(new IdRef(editId)); 242 doc.setPropertyValue("dc:title", title); 243 doc.setPropertyValue("file:content", (Serializable) Blobs.createBlob(content)); 244 DocumentationItem item = doc.getAdapter(DocumentationItem.class); 245 246 ds.updateDocumentationItem(getContext().getCoreSession(), item); 247 } 248 249 return "OK"; 250 } 251 252 public Map<String, String> getCategories() { 253 DocumentationService ds = Framework.getService(DocumentationService.class); 254 return ds.getCategories(); 255 } 256 257 public String getSearchCriterion() { 258 return String.format("'%s'", getNxArtifactId()); 259 } 260}