001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.core.rest;
021
022import javax.servlet.http.HttpServletRequest;
023import javax.ws.rs.DELETE;
024import javax.ws.rs.GET;
025import javax.ws.rs.POST;
026import javax.ws.rs.PUT;
027import javax.ws.rs.Path;
028import javax.ws.rs.PathParam;
029import javax.ws.rs.Produces;
030import javax.ws.rs.core.Response;
031
032import org.nuxeo.common.utils.URIUtils;
033import org.nuxeo.ecm.core.api.CoreSession;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.api.DocumentModelList;
036import org.nuxeo.ecm.core.api.DocumentRef;
037import org.nuxeo.ecm.core.api.NuxeoException;
038import org.nuxeo.ecm.core.api.PathRef;
039import org.nuxeo.ecm.webengine.WebException;
040import org.nuxeo.ecm.webengine.model.Resource;
041import org.nuxeo.ecm.webengine.model.WebObject;
042import org.nuxeo.ecm.webengine.model.exceptions.IllegalParameterException;
043import org.nuxeo.ecm.webengine.model.impl.DefaultObject;
044
045/**
046 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
047 */
048@WebObject(type = "Document")
049@Produces("text/html; charset=UTF-8")
050public class DocumentObject extends DefaultObject {
051
052    protected DocumentModel doc;
053
054    @Override
055    public <A> A getAdapter(Class<A> adapter) {
056        if (adapter == DocumentModel.class) {
057            return adapter.cast(doc);
058        }
059        return super.getAdapter(adapter);
060    }
061
062    @Override
063    public void initialize(Object... args) {
064        assert args != null && args.length == 1;
065        doc = (DocumentModel) args[0];
066    }
067
068    @GET
069    public Object doGet() {
070        return getView("index");
071    }
072
073    // simulate a DELETE using GET
074    @GET
075    @Path("@delete")
076    public Response getDelete() {
077        return doDelete();
078    }
079
080    @GET
081    @Path("@search")
082    public Object search() {
083        final HttpServletRequest request = ctx.getRequest();
084        String query = request.getParameter("query");
085        if (query == null) {
086            String fullText = request.getParameter("fullText");
087            if (fullText == null) {
088                throw new IllegalParameterException("Expecting a query or a fullText parameter");
089            }
090            String orderBy = request.getParameter("orderBy");
091            String orderClause = "";
092            if (orderBy != null) {
093                orderClause = " ORDER BY " + orderBy;
094            }
095            String path;
096            if (doc.isFolder()) {
097                path = doc.getPathAsString();
098            } else {
099                path = doc.getPath().removeLastSegments(1).toString();
100            }
101            query = "SELECT * FROM Document WHERE (ecm:fulltext = \"" + fullText
102                    + "\") AND (ecm:isCheckedInVersion = 0) AND (ecm:path STARTSWITH \"" + path + "\")" + orderClause;
103        }
104        try {
105            DocumentModelList docs = ctx.getCoreSession().query(query);
106            return getView("search").arg("query", query).arg("result", docs);
107        } catch (NuxeoException e) {
108            throw WebException.wrap(e);
109        }
110    }
111
112    @DELETE
113    public Response doDelete() {
114        try {
115            CoreSession session = ctx.getCoreSession();
116            session.removeDocument(doc.getRef());
117            session.save();
118        } catch (NuxeoException e) {
119            throw WebException.wrap("Failed to delete document " + doc.getPathAsString(), e);
120        }
121        if (prev != null) { // show parent ? TODO: add getView(method) to be able to change the view method
122            return redirect(prev.getPath());
123        }
124        return redirect(ctx.getBasePath());
125    }
126
127    @POST
128    public Response doPost() {
129        String name = ctx.getForm().getString("name");
130        DocumentModel newDoc = DocumentHelper.createDocument(ctx, doc, name);
131        String pathSegment = URIUtils.quoteURIPathComponent(newDoc.getName(), true);
132        return redirect(getPath() + '/' + pathSegment);
133    }
134
135    @PUT
136    public Response doPut() {
137        doc = DocumentHelper.updateDocument(ctx, doc);
138        return redirect(getPath());
139    }
140
141    @POST
142    @Path("@put")
143    public Response getPut() {
144        return doPut();
145    }
146
147    // TODO implement HEAD
148    public Object doHead() {
149        return null; // TODO
150    }
151
152    @Path("{path}")
153    public Resource traverse(@PathParam("path") String path) {
154        return newDocument(path);
155    }
156
157    public DocumentObject newDocument(String path) {
158        try {
159            PathRef pathRef = new PathRef(doc.getPath().append(path).toString());
160            DocumentModel doc = ctx.getCoreSession().getDocument(pathRef);
161            return (DocumentObject) ctx.newObject(doc.getType(), doc);
162        } catch (NuxeoException e) {
163            throw WebException.wrap(e);
164        }
165    }
166
167    public DocumentObject newDocument(DocumentRef ref) {
168        try {
169            DocumentModel doc = ctx.getCoreSession().getDocument(ref);
170            return (DocumentObject) ctx.newObject(doc.getType(), doc);
171        } catch (NuxeoException e) {
172            throw WebException.wrap(e);
173        }
174    }
175
176    public DocumentObject newDocument(DocumentModel doc) {
177        return (DocumentObject) ctx.newObject(doc.getType(), doc);
178    }
179
180    public CoreSession getCoreSession() {
181        return ctx.getCoreSession();
182    }
183
184    public DocumentModel getDocument() {
185        return doc;
186    }
187
188    public String getTitle() {
189        try {
190            return doc.getTitle();
191        } catch (NuxeoException e) {
192            throw WebException.wrap(e);
193        }
194    }
195
196}