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