001/*
002 * (C) Copyright 2006-2008 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 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.core.rest;
023
024import javax.servlet.http.HttpServletRequest;
025import javax.ws.rs.DELETE;
026import javax.ws.rs.GET;
027import javax.ws.rs.POST;
028import javax.ws.rs.PUT;
029import javax.ws.rs.Path;
030import javax.ws.rs.PathParam;
031import javax.ws.rs.Produces;
032import javax.ws.rs.core.Response;
033
034import org.nuxeo.common.utils.URIUtils;
035import org.nuxeo.ecm.core.api.CoreSession;
036import org.nuxeo.ecm.core.api.DocumentModel;
037import org.nuxeo.ecm.core.api.DocumentModelList;
038import org.nuxeo.ecm.core.api.DocumentRef;
039import org.nuxeo.ecm.core.api.NuxeoException;
040import org.nuxeo.ecm.core.api.PathRef;
041import org.nuxeo.ecm.webengine.model.Resource;
042import org.nuxeo.ecm.webengine.model.WebObject;
043import org.nuxeo.ecm.webengine.model.exceptions.IllegalParameterException;
044import org.nuxeo.ecm.webengine.model.impl.DefaultObject;
045
046/**
047 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
048 */
049@WebObject(type = "Document")
050@Produces("text/html; charset=UTF-8")
051public class DocumentObject extends DefaultObject {
052
053    protected DocumentModel doc;
054
055    @Override
056    public <A> A getAdapter(Class<A> adapter) {
057        if (adapter == DocumentModel.class) {
058            return adapter.cast(doc);
059        }
060        return super.getAdapter(adapter);
061    }
062
063    @Override
064    public void initialize(Object... args) {
065        assert args != null && args.length == 1;
066        doc = (DocumentModel) args[0];
067    }
068
069    @GET
070    public Object doGet() {
071        return getView("index");
072    }
073
074    // simulate a DELETE using GET
075    @GET
076    @Path("@delete")
077    public Response getDelete() {
078        return doDelete();
079    }
080
081    @GET
082    @Path("@search")
083    public Object search() {
084        final HttpServletRequest request = ctx.getRequest();
085        String query = request.getParameter("query");
086        if (query == null) {
087            String fullText = request.getParameter("fullText");
088            if (fullText == null) {
089                throw new IllegalParameterException("Expecting a query or a fullText parameter");
090            }
091            String orderBy = request.getParameter("orderBy");
092            String orderClause = "";
093            if (orderBy != null) {
094                orderClause = " ORDER BY " + orderBy;
095            }
096            String path;
097            if (doc.isFolder()) {
098                path = doc.getPathAsString();
099            } else {
100                path = doc.getPath().removeLastSegments(1).toString();
101            }
102            query = "SELECT * FROM Document WHERE (ecm:fulltext = \"" + fullText
103                    + "\") AND (ecm:isCheckedInVersion = 0) AND (ecm:path STARTSWITH \"" + path + "\")" + orderClause;
104        }
105        DocumentModelList docs = ctx.getCoreSession().query(query);
106        return getView("search").arg("query", query).arg("result", docs);
107    }
108
109    @DELETE
110    public Response doDelete() {
111        try {
112            CoreSession session = ctx.getCoreSession();
113            session.removeDocument(doc.getRef());
114            session.save();
115        } catch (NuxeoException e) {
116            e.addInfo("Failed to delete document " + doc.getPathAsString());
117            throw e;
118        }
119        if (prev != null) { // show parent ? TODO: add getView(method) to be able to change the view method
120            return redirect(prev.getPath());
121        }
122        return redirect(ctx.getBasePath());
123    }
124
125    @POST
126    public Response doPost() {
127        String name = ctx.getForm().getString("name");
128        DocumentModel newDoc = DocumentHelper.createDocument(ctx, doc, name);
129        String pathSegment = URIUtils.quoteURIPathComponent(newDoc.getName(), true);
130        return redirect(getPath() + '/' + pathSegment);
131    }
132
133    @PUT
134    public Response doPut() {
135        doc = DocumentHelper.updateDocument(ctx, doc);
136        return redirect(getPath());
137    }
138
139    @POST
140    @Path("@put")
141    public Response getPut() {
142        return doPut();
143    }
144
145    // TODO implement HEAD
146    public Object doHead() {
147        return null; // TODO
148    }
149
150    @Path("{path}")
151    public Resource traverse(@PathParam("path") String path) {
152        return newDocument(path);
153    }
154
155    public DocumentObject newDocument(String path) {
156        PathRef pathRef = new PathRef(doc.getPath().append(path).toString());
157        DocumentModel doc = ctx.getCoreSession().getDocument(pathRef);
158        return (DocumentObject) ctx.newObject(doc.getType(), doc);
159    }
160
161    public DocumentObject newDocument(DocumentRef ref) {
162        DocumentModel doc = ctx.getCoreSession().getDocument(ref);
163        return (DocumentObject) ctx.newObject(doc.getType(), doc);
164    }
165
166    public DocumentObject newDocument(DocumentModel doc) {
167        return (DocumentObject) ctx.newObject(doc.getType(), doc);
168    }
169
170    public CoreSession getCoreSession() {
171        return ctx.getCoreSession();
172    }
173
174    public DocumentModel getDocument() {
175        return doc;
176    }
177
178    public String getTitle() {
179        return doc.getTitle();
180    }
181
182}