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.nuxeo.apidoc.api.AssociatedDocuments; 038import org.nuxeo.apidoc.api.DocumentationItem; 039import org.nuxeo.apidoc.api.NuxeoArtifact; 040import org.nuxeo.apidoc.doc.SimpleDocumentationItem; 041import org.nuxeo.apidoc.documentation.DocumentationService; 042import org.nuxeo.apidoc.snapshot.SnapshotManager; 043import org.nuxeo.ecm.core.api.Blobs; 044import org.nuxeo.ecm.core.api.DocumentModel; 045import org.nuxeo.ecm.core.api.IdRef; 046import org.nuxeo.ecm.webengine.model.Template; 047import org.nuxeo.ecm.webengine.model.exceptions.WebSecurityException; 048import org.nuxeo.ecm.webengine.model.impl.DefaultObject; 049import org.nuxeo.runtime.api.Framework; 050 051public abstract class NuxeoArtifactWebObject extends DefaultObject { 052 053 protected String nxArtifactId; 054 055 @Override 056 protected void initialize(Object... args) { 057 nxArtifactId = (String) args[0]; 058 } 059 060 protected String getNxArtifactId() { 061 return nxArtifactId; 062 } 063 064 protected SnapshotManager getSnapshotManager() { 065 return Framework.getLocalService(SnapshotManager.class); 066 } 067 068 @Override 069 public Template getView(String viewId) { 070 return super.getView(viewId).arg(Distribution.DIST_ID, getDistributionId()).arg("enableDocumentationView", 071 Boolean.TRUE); 072 } 073 074 public abstract NuxeoArtifact getNxArtifact(); 075 076 protected abstract Object doGet(); 077 078 protected String getDistributionId() { 079 return (String) ctx.getProperty(Distribution.DIST_ID); 080 } 081 082 public AssociatedDocuments getAssociatedDocuments() { 083 NuxeoArtifact nxItem = getNxArtifact(); 084 return nxItem.getAssociatedDocuments(ctx.getCoreSession()); 085 } 086 087 @POST 088 @Produces("text/html") 089 @Path("updateDocumentation") 090 public Object doUpdateDocumentation(DocumentationItem docItem) { 091 if (!SecurityHelper.canEditDocumentation(getContext())) { 092 throw new WebSecurityException("You are not allowed to do this operation"); 093 } 094 095 DocumentationService ds = Framework.getLocalService(DocumentationService.class); 096 097 ds.updateDocumentationItem(ctx.getCoreSession(), docItem); 098 return redirect(getDocUrl()); 099 } 100 101 protected String getDocUrl() { 102 String path = getPath() + "/doc"; 103 // //TODO encode path segments if needed 104 return path; 105 } 106 107 @Deprecated 108 protected String computeUrl(String suffix) throws UnsupportedEncodingException { 109 String targetUrl = ctx.getUrlPath(); 110 targetUrl = URLDecoder.decode(targetUrl, "ISO-8859-1"); 111 targetUrl = targetUrl.replace(ctx.getBasePath(), ""); 112 targetUrl = targetUrl.replace(suffix, "/doc"); 113 targetUrl = URLEncoder.encode(targetUrl, "ISO-8859-1"); 114 return targetUrl; 115 } 116 117 @POST 118 @Produces("text/html") 119 @Path("createDocumentation") 120 public Object doCreateDocumentation(DocumentationItem docItem) { 121 if (!SecurityHelper.canEditDocumentation(getContext())) { 122 throw new WebSecurityException("You are not allowed to do this operation"); 123 } 124 125 DocumentationService ds = Framework.getLocalService(DocumentationService.class); 126 ds.createDocumentationItem(ctx.getCoreSession(), getNxArtifact(), docItem.getTitle(), docItem.getContent(), 127 docItem.getType(), docItem.getApplicableVersion(), docItem.isApproved(), docItem.getRenderingType()); 128 return redirect(getDocUrl()); 129 } 130 131 @POST 132 @Produces("text/html") 133 @Path("deleteDocumentation") 134 public Object doDeleteDocumentation(@FormParam("uuid") String uuid) { 135 if (!SecurityHelper.canEditDocumentation(getContext())) { 136 throw new WebSecurityException("You are not allowed to do this operation"); 137 } 138 DocumentationService ds = Framework.getLocalService(DocumentationService.class); 139 ds.deleteDocumentationItem(ctx.getCoreSession(), uuid); 140 return redirect(getDocUrl()); 141 } 142 143 @GET 144 @Produces("text/html") 145 public Object doViewDefault() { 146 NuxeoArtifact nxItem = getNxArtifact(); 147 AssociatedDocuments docs = nxItem.getAssociatedDocuments(ctx.getCoreSession()); 148 return getView("default").arg("nxItem", nxItem).arg("docs", docs).arg("selectedTab", "defView"); 149 } 150 151 @GET 152 @Produces("text/html") 153 @Path("doc") 154 public Object doViewDoc() { 155 NuxeoArtifact nxItem = getNxArtifact(); 156 AssociatedDocuments docs = nxItem.getAssociatedDocuments(ctx.getCoreSession()); 157 return getView("../documentation").arg("nxItem", nxItem).arg("docs", docs).arg("selectedTab", "docView"); 158 } 159 160 @GET 161 @Produces("text/html") 162 @Path("aggregated") 163 public Object doViewAggregated() { 164 NuxeoArtifact nxItem = getNxArtifact(); 165 AssociatedDocuments docs = nxItem.getAssociatedDocuments(ctx.getCoreSession()); 166 return getView("aggregated").arg("nxItem", nxItem).arg("docs", docs).arg("selectedTab", "aggView"); 167 } 168 169 @GET 170 @Produces("text/html") 171 @Path("createForm") 172 public Object doAddDoc(@QueryParam("inline") Boolean inline, @QueryParam("type") String type) { 173 NuxeoArtifact nxItem = getNxArtifact(); 174 List<String> versions = getSnapshotManager().getAvailableVersions(ctx.getCoreSession(), nxItem); 175 DocumentationItem docItem = new SimpleDocumentationItem(nxItem); 176 String targetView = "../docForm"; 177 if (inline != null && inline.equals(Boolean.TRUE)) { 178 targetView = "../../docItemForm"; 179 } 180 return getView(targetView).arg("nxItem", nxItem).arg("mode", "create").arg("docItem", docItem).arg("versions", 181 versions).arg("selectedTab", "docView").arg("preselectedType", type); 182 } 183 184 @GET 185 @Produces("text/html") 186 @Path("editForm/{uuid}") 187 public Object doEditDoc(@PathParam("uuid") String uuid) { 188 NuxeoArtifact nxItem = getNxArtifact(); 189 List<String> versions = getSnapshotManager().getAvailableVersions(ctx.getCoreSession(), nxItem); 190 DocumentModel existingDoc = ctx.getCoreSession().getDocument(new IdRef(uuid)); 191 DocumentationItem docItem = existingDoc.getAdapter(DocumentationItem.class); 192 return getView("../docForm").arg("nxItem", nxItem).arg("mode", "edit").arg("docItem", docItem).arg("versions", 193 versions).arg("selectedTab", "docView"); 194 } 195 196 @GET 197 @Produces("text/plain") 198 @Path("quickEdit/{editId}") 199 public Object quickEdit(@PathParam("editId") String editId) { 200 201 if (editId == null || editId.startsWith("placeholder_")) { 202 return ""; 203 } 204 205 DocumentModel doc = getContext().getCoreSession().getDocument(new IdRef(editId)); 206 DocumentationItem item = doc.getAdapter(DocumentationItem.class); 207 208 return item.getContent(); 209 } 210 211 @POST 212 @Produces("text/plain") 213 @Path("quickEdit/{editId}") 214 public Object quickEditSave(@PathParam("editId") String editId) { 215 216 String title = getContext().getForm().getString("title"); 217 String content = getContext().getForm().getString("content"); 218 String type = getContext().getForm().getString("type"); 219 if (type == null || type.trim().length() == 0) { 220 type = "description"; 221 } 222 223 String renderingType = "wiki"; 224 if (content.contains("<ul>") || content.contains("<p>") || content.contains("<br/>")) { 225 renderingType = "html"; 226 } 227 228 List<String> applicableVersions = new ArrayList<String>(); 229 applicableVersions.add(getSnapshotManager().getSnapshot(getDistributionId(), getContext().getCoreSession()).getVersion()); // XXX 230 // !!! 231 DocumentationService ds = Framework.getLocalService(DocumentationService.class); 232 if (editId == null || editId.startsWith("placeholder_")) { 233 ds.createDocumentationItem(getContext().getCoreSession(), getNxArtifact(), title, content, type, 234 applicableVersions, false, renderingType); 235 } else { 236 DocumentModel doc = getContext().getCoreSession().getDocument(new IdRef(editId)); 237 doc.setPropertyValue("dc:title", title); 238 doc.setPropertyValue("file:content", (Serializable) Blobs.createBlob(content)); 239 DocumentationItem item = doc.getAdapter(DocumentationItem.class); 240 241 ds.updateDocumentationItem(getContext().getCoreSession(), item); 242 } 243 244 return "OK"; 245 } 246 247 public Map<String, String> getCategories() { 248 DocumentationService ds = Framework.getLocalService(DocumentationService.class); 249 return ds.getCategories(); 250 } 251 252}