001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (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 *     Nuxeo
016 *     Florent Guillaume
017 */
018
019package org.nuxeo.ecm.platform.ui.web.restAPI;
020
021import org.dom4j.dom.DOMDocument;
022import org.dom4j.dom.DOMDocumentFactory;
023import org.joda.time.DateTime;
024import org.joda.time.format.ISODateTimeFormat;
025import org.nuxeo.ecm.core.api.Lock;
026import org.nuxeo.ecm.core.api.NuxeoException;
027import org.restlet.data.CharacterSet;
028import org.restlet.data.MediaType;
029import org.restlet.data.Method;
030import org.restlet.data.Request;
031import org.restlet.data.Response;
032import org.w3c.dom.Element;
033
034/**
035 * Restlet returning the locking information on a document.
036 */
037public class LockingRestlet extends BaseStatelessNuxeoRestlet {
038
039    public static final String LOCK = "lock";
040
041    public static final String UNLOCK = "unlock";
042
043    public static final String STATUS = "status";
044
045    public static final String STATE = "state";
046
047    public static final String SC_LOCKINFO_LOCKED = "LOCKED";
048
049    public static final String SC_LOCKINFO_NOT_LOCKED = "NOTLOCKED";
050
051    public static final String SC_LOCKED_OK = "OK";
052
053    public static final String SC_ALREADY_LOCKED_KO = "ALREADYLOCKED";
054
055    public static final String SC_ALREADY_LOCKED_OK = "ALREADYLOCKEDBYYOU";
056
057    public static final String SC_UNLOCKED_OK = "OK";
058
059    public static final String SC_ALREADY_UNLOCKED_OK = "NOT LOCKED";
060
061    @Override
062    protected void doHandleStatelessRequest(Request req, Response res) {
063
064        String repoId = (String) req.getAttributes().get("repo");
065        String docid = (String) req.getAttributes().get("docid");
066
067        DOMDocumentFactory domFactory = new DOMDocumentFactory();
068        DOMDocument result = (DOMDocument) domFactory.createDocument();
069
070        // init repo and document
071        boolean initOk = initRepositoryAndTargetDocument(res, repoId, docid);
072        if (!initOk) {
073            return;
074        }
075
076        String cUserName = getUserPrincipal(req).getName();
077
078        // get Action
079        String action = STATUS;
080        if (req.getResourceRef().getSegments().size() > 5) {
081            action = req.getResourceRef().getSegments().get(5).toLowerCase();
082        }
083        if (req.getMethod().equals(Method.LOCK)) {
084            action = LOCK;
085        }
086        if (req.getMethod().equals(Method.UNLOCK)) {
087            action = UNLOCK;
088        }
089
090        String response = "";
091        String code = "";
092        if (action.equals(LOCK)) {
093            try {
094                Lock lock = session.getLockInfo(targetDocRef);
095                if (lock == null) {
096                    session.setLock(targetDocRef);
097                    session.save();
098                    response = "lock acquired on document " + docid;
099                    code = SC_LOCKED_OK;
100                } else if (lock.getOwner().equals(cUserName)) {
101                    response = "document " + docid + " is already locked by you";
102                    code = SC_ALREADY_LOCKED_OK;
103                } else {
104                    response = "document " + docid + " is already locked by " + lock.getOwner();
105                    code = SC_ALREADY_LOCKED_KO;
106                }
107            } catch (NuxeoException e) {
108                handleError(result, res, e);
109                return;
110            }
111        } else if (action.equals(UNLOCK)) {
112
113            try {
114                Lock lock = session.getLockInfo(targetDocRef);
115                if (lock == null) {
116                    response = "document " + docid + " is not locked";
117                    code = SC_ALREADY_UNLOCKED_OK;
118                } else if (lock.getOwner().equals(cUserName)) {
119                    session.removeLock(targetDocRef);
120                    session.save();
121                    response = "document " + docid + " unlocked";
122                    code = SC_UNLOCKED_OK;
123                } else {
124                    response = "document " + docid + " is locked by " + lock.getOwner();
125                    code = SC_ALREADY_LOCKED_KO;
126                }
127            } catch (NuxeoException e) {
128                handleError(result, res, e);
129                return;
130            }
131
132        } else if (action.equals(STATUS)) {
133            try {
134                Lock lock = session.getLockInfo(targetDocRef);
135                response = session.getLock(targetDocRef);
136                if (lock == null) {
137                    code = SC_LOCKINFO_NOT_LOCKED;
138                } else {
139                    code = SC_LOCKINFO_LOCKED;
140                }
141            } catch (NuxeoException e) {
142                handleError(result, res, e);
143                return;
144            }
145
146        } else if (action.equals(STATE)) {
147            try {
148                Lock lock = session.getLockInfo(targetDocRef);
149                if (lock == null) {
150                    code = SC_LOCKINFO_NOT_LOCKED;
151                    response = "";
152                } else {
153                    code = SC_LOCKINFO_LOCKED;
154                    response = lock.getOwner() + '/'
155                            + ISODateTimeFormat.dateTime().print(new DateTime(lock.getCreated()));
156                }
157            } catch (NuxeoException e) {
158                handleError(result, res, e);
159                return;
160            }
161
162        } else {
163            handleError(result, res, "Unsupported operation");
164            return;
165        }
166
167        Element current = result.createElement("document");
168        current.setAttribute("code", code);
169        current.setAttribute("message", response);
170        result.setRootElement((org.dom4j.Element) current);
171        res.setEntity(result.asXML(), MediaType.TEXT_XML);
172        res.getEntity().setCharacterSet(CharacterSet.UTF_8);
173    }
174
175}