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}