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