001/*
002 * (C) Copyright 2006-2011 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 */
019package org.nuxeo.ecm.automation.client.adapters;
020
021import java.io.IOException;
022import java.util.Arrays;
023
024import org.apache.commons.lang.StringUtils;
025import org.nuxeo.ecm.automation.client.Constants;
026import org.nuxeo.ecm.automation.client.OperationRequest;
027import org.nuxeo.ecm.automation.client.Session;
028import org.nuxeo.ecm.automation.client.model.Blob;
029import org.nuxeo.ecm.automation.client.model.Blobs;
030import org.nuxeo.ecm.automation.client.model.DocRef;
031import org.nuxeo.ecm.automation.client.model.Document;
032import org.nuxeo.ecm.automation.client.model.Documents;
033import org.nuxeo.ecm.automation.client.model.FileBlob;
034import org.nuxeo.ecm.automation.client.model.PathRef;
035import org.nuxeo.ecm.automation.client.model.PropertyMap;
036
037/**
038 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
039 */
040public class DocumentService {
041
042    public static final String FetchDocument = "Repository.GetDocument";
043
044    public static final String CreateDocument = "Document.Create";
045
046    public static final String DeleteDocument = "Document.Delete";
047
048    public static final String CopyDocument = "Document.Copy";
049
050    public static final String MoveDocument = "Document.Move";
051
052    public static final String GetDocumentChildren = "Document.GetChildren";
053
054    public static final String GetDocumentChild = "Document.GetChild";
055
056    public static final String GetDocumentParent = "Document.GetParent";
057
058    public static final String Query = "Repository.Query";
059
060    public static final String SetPermission = "Document.AddACE";
061
062    public static final String RemoveAcl = "Document.RemoveACL";
063
064    public static final String SetDocumentState = "Document.FollowLifecycleTransition";
065
066    public static final String LockDocument = "Document.Lock";
067
068    public static final String UnlockDocument = "Document.Unlock";
069
070    public static final String SetProperty = "Document.SetProperty";
071
072    public static final String RemoveProperty = "Document.RemoveProperty";
073
074    public static final String UpdateDocument = "Document.Update";
075
076    public static final String PublishDocument = "Document.Publish";
077
078    public static final String CreateRelation = "Document.AddRelation";
079
080    public static final String GetRelations = "Document.GetLinkedDocuments";
081
082    public static final String SetBlob = "Blob.AttachOnDocument";
083
084    public static final String RemoveBlob = "Blob.RemoveFromDocument";
085
086    public static final String GetBlob = "Document.GetBlob";
087
088    public static final String GetBlobs = "Document.GetBlobsByProperty";
089
090    public static final String CreateVersion = "Document.CreateVersion";
091
092    public static final String FireEvent = "Event.Fire";
093
094    // The following are not yet implemented
095    public static final String CheckOut = "Document.CheckOut";
096
097    public static final String CheckIn = "Document.CheckIn";
098
099    // //TODO GetAcl?
100    protected Session session;
101
102    public DocumentService(Session session) {
103        this.session = session;
104    }
105
106    public Session getSession() {
107        return session;
108    }
109
110    public Document getDocument(String ref) throws IOException {
111        return getDocument(DocRef.newRef(ref), null);
112    }
113
114    /**
115     * @since 5.7
116     * @param document document to fetch
117     * @param schemas schemas related to the document to fetch (* for all)
118     * @return the document returned by server
119     */
120    public Document getDocument(Document document, String... schemas) throws IOException {
121        return getDocument(new DocRef(document.getId()), StringUtils.join(Arrays.asList(schemas), ","));
122    }
123
124    public Document getDocument(DocRef ref) throws IOException {
125        return getDocument(ref, null);
126    }
127
128    public Document getDocument(DocRef ref, String schemas) throws IOException {
129        OperationRequest req = session.newRequest(FetchDocument).set("value", ref);
130        if (schemas != null) {
131            req.setHeader(Constants.HEADER_NX_SCHEMAS, schemas);
132        }
133        return (Document) req.execute();
134    }
135
136    public Document getRootDocument() throws IOException {
137        return getDocument(new PathRef("/"));
138    }
139
140    /**
141     * @since 5.7
142     * @param parent can be PathRef or IdRef
143     * @param document the document to create
144     * @return the document created
145     */
146    public Document createDocument(String parent, Document document) throws IOException {
147        return createDocument(DocRef.newRef(parent), document.getType(), document.getId(), document.getDirties());
148    }
149
150    public Document createDocument(DocRef parent, String type, String name) throws IOException {
151        return createDocument(parent, type, name, null);
152    }
153
154    public Document createDocument(DocRef parent, String type, String name, PropertyMap properties) throws IOException {
155        OperationRequest req = session.newRequest(CreateDocument).setInput(parent).set("type", type).set("name", name);
156        if (properties != null && !properties.isEmpty()) {
157            req.set("properties", properties);
158        }
159        return (Document) req.execute();
160    }
161
162    /**
163     * @since 5.7
164     * @param document the document to remove
165     */
166    public void remove(Document document) throws IOException {
167        remove(new DocRef(document.getId()));
168    }
169
170    public void remove(DocRef doc) throws IOException {
171        session.newRequest(DeleteDocument).setInput(doc).execute();
172    }
173
174    public void remove(String ref) throws IOException {
175        session.newRequest(DeleteDocument).setInput(DocRef.newRef(ref)).execute();
176    }
177
178    public Document copy(DocRef src, DocRef targetParent) throws IOException {
179        return copy(src, targetParent, null);
180    }
181
182    public Document copy(DocRef src, DocRef targetParent, String name) throws IOException {
183        OperationRequest req = session.newRequest(CopyDocument).setInput(src).set("target", targetParent);
184        if (name != null) {
185            req.set("name", name);
186        }
187        return (Document) req.execute();
188    }
189
190    public Document move(DocRef src, DocRef targetParent) throws IOException {
191        return move(src, targetParent, null);
192    }
193
194    public Document move(DocRef src, DocRef targetParent, String name) throws IOException {
195        OperationRequest req = session.newRequest(MoveDocument).setInput(src).set("target", targetParent);
196        if (name != null) {
197            req.set("name", name);
198        }
199        return (Document) req.execute();
200    }
201
202    public Documents getChildren(DocRef docRef) throws IOException {
203        return (Documents) session.newRequest(GetDocumentChildren).setInput(docRef).execute();
204    }
205
206    public Document getChild(DocRef docRef, String name) throws IOException {
207        return (Document) session.newRequest(GetDocumentChild).setInput(docRef).set("name", name).execute();
208    }
209
210    public Document getParent(DocRef docRef) throws IOException {
211        return (Document) session.newRequest(GetDocumentParent).setInput(docRef).execute();
212    }
213
214    public Documents getParent(DocRef docRef, String type) throws IOException {
215        return (Documents) session.newRequest(GetDocumentParent).setInput(docRef).set("type", type).execute();
216    }
217
218    public Documents query(String query) throws IOException {
219        return (Documents) session.newRequest(Query).set("query", query).execute();
220    }
221
222    public Document setPermission(DocRef doc, String user, String permission) throws IOException {
223        return setPermission(doc, user, permission, null, true);
224    }
225
226    public Document setPermission(DocRef doc, String user, String permission, boolean granted) throws IOException {
227        return setPermission(doc, user, permission, null, granted);
228    }
229
230    public Document setPermission(DocRef doc, String user, String permission, String acl, boolean granted)
231            throws IOException {
232        OperationRequest req = session.newRequest(SetPermission).setInput(doc).set("user", user).set("permission",
233                permission).set("grant", granted);
234        if (acl != null) {
235            req.set("acl", acl);
236        }
237        return (Document) req.execute();
238    }
239
240    public Document removeAcl(DocRef doc, String acl) throws IOException {
241        return (Document) session.newRequest(RemoveAcl).setInput(doc).set("acl", acl).execute();
242    }
243
244    public Document setState(DocRef doc, String state) throws IOException {
245        return (Document) session.newRequest(SetDocumentState).setInput(doc).set("value", state).execute();
246    }
247
248    public Document lock(DocRef doc) throws IOException {
249        return lock(doc, null);
250    }
251
252    public Document lock(DocRef doc, String lock) throws IOException {
253        OperationRequest req = session.newRequest(LockDocument).setInput(doc);
254        if (lock != null) {
255            req.set("owner", lock);
256        }
257        return (Document) req.execute();
258    }
259
260    public Document unlock(DocRef doc) throws IOException {
261        return (Document) session.newRequest(UnlockDocument).setInput(doc).execute();
262    }
263
264    // TODO: value Serializable?
265    public Document setProperty(DocRef doc, String key, String value) throws IOException {
266        return (Document) session.newRequest(SetProperty).setInput(doc).set("xpath", key).set("value", value).execute();
267    }
268
269    public Document removeProperty(DocRef doc, String key) throws IOException {
270        return (Document) session.newRequest(RemoveProperty).setInput(doc).set("xpath", key).execute();
271    }
272
273    /**
274     * This method sends the dirty properties to server
275     *
276     * @since 5.7
277     * @param document the document to update
278     * @return the document returned by the server
279     */
280    public Document update(Document document) throws IOException {
281        return update(new DocRef(document.getId()), document.getDirties());
282    }
283
284    public Document update(DocRef doc, PropertyMap properties) throws IOException {
285        return (Document) session.newRequest(UpdateDocument).setInput(doc).set("properties", properties).execute();
286    }
287
288    public Document publish(DocRef doc, DocRef section) throws IOException {
289        return publish(doc, section, true);
290    }
291
292    public Document publish(DocRef doc, DocRef section, boolean override) throws IOException {
293        return (Document) session.newRequest(PublishDocument).setInput(doc).set("target", section).set("override",
294                override).execute();
295    }
296
297    public Document createRelation(DocRef subject, String predicate, DocRef object) throws IOException {
298        return (Document) session.newRequest(CreateRelation).setInput(subject).set("object", object).set("predicate",
299                predicate).execute();
300    }
301
302    public Documents getRelations(DocRef doc, String predicate) throws IOException {
303        return getRelations(doc, predicate, true);
304    }
305
306    public Documents getRelations(DocRef doc, String predicate, boolean outgoing) throws IOException {
307        return (Documents) session.newRequest(GetRelations).setInput(doc).set("predicate", predicate).set("outgoing",
308                outgoing).execute();
309    }
310
311    /**
312     * @since 5.5
313     */
314    public Documents getRelations(DocRef doc, String predicate, boolean outgoing, String graphName) throws IOException {
315        return (Documents) session.newRequest(GetRelations).setInput(doc).set("predicate", predicate).set("outgoing",
316                outgoing).set("graphName", graphName).execute();
317    }
318
319    public void setBlob(DocRef doc, Blob blob) throws IOException {
320        setBlob(doc, blob, null);
321    }
322
323    public void setBlob(DocRef doc, Blob blob, String xpath) throws IOException {
324        OperationRequest req = session.newRequest(SetBlob).setInput(blob).set("document", doc);
325        if (xpath != null) {
326            req.set("xpath", xpath);
327        }
328        req.setHeader(Constants.HEADER_NX_VOIDOP, "true");
329        req.execute();
330    }
331
332    public void removeBlob(DocRef doc) throws IOException {
333        removeBlob(doc, null);
334    }
335
336    public void removeBlob(DocRef doc, String xpath) throws IOException {
337        OperationRequest req = session.newRequest(RemoveBlob).setInput(doc);
338        if (xpath != null) {
339            req.set("xpath", xpath);
340        }
341        req.setHeader(Constants.HEADER_NX_VOIDOP, "true");
342        req.execute();
343    }
344
345    public FileBlob getBlob(DocRef doc) throws IOException {
346        return getBlob(doc, null);
347    }
348
349    public FileBlob getBlob(DocRef doc, String xpath) throws IOException {
350        OperationRequest req = session.newRequest(GetBlob).setInput(doc);
351        if (xpath != null) {
352            req.set("xpath", xpath);
353        }
354        return (FileBlob) req.execute();
355    }
356
357    public Blobs getBlobs(DocRef doc) throws IOException {
358        return getBlobs(doc, null);
359    }
360
361    public Blobs getBlobs(DocRef doc, String xpath) throws IOException {
362        OperationRequest req = session.newRequest(GetBlobs).setInput(doc);
363        if (xpath != null) {
364            req.set("xpath", xpath);
365        }
366        return (Blobs) req.execute();
367    }
368
369    public Document createVersion(DocRef doc) throws IOException {
370        return createVersion(doc, null);
371    }
372
373    /**
374     * Increment is one of "None", "Major", "Minor". If null the server default will be used. See
375     * {@link VersionIncrement}
376     */
377    public Document createVersion(DocRef doc, String increment) throws IOException {
378        OperationRequest req = session.newRequest(CreateVersion).setInput(doc);
379        if (increment != null) {
380            req.set("increment", increment);
381        }
382        return (Document) req.execute();
383    }
384
385    public void fireEvent(String event) throws IOException {
386        fireEvent(null, event);
387    }
388
389    public void fireEvent(DocRef doc, String event) throws IOException {
390        OperationRequest req = session.newRequest(CreateVersion).setInput(doc);
391        req.setHeader(Constants.HEADER_NX_VOIDOP, "true");
392        req.execute();
393    }
394}