Revision 92012b4d
b/gss/src/gr/ebs/gss/server/webdav/Webdav.java | ||
---|---|---|
274 | 274 |
*/ |
275 | 275 |
private String secret = "gss-webdav"; |
276 | 276 |
|
277 |
/** |
|
278 |
* Repository of the locks put on single resources. |
|
279 |
* <p> |
|
280 |
* Key : path <br> |
|
281 |
* Value : LockInfo |
|
282 |
*/ |
|
283 |
private Hashtable<String, LockInfo> resourceLocks = new Hashtable<String, LockInfo>(); |
|
284 |
|
|
285 |
/** |
|
286 |
* Repository of the lock-null resources. |
|
287 |
* <p> |
|
288 |
* Key : path of the collection containing the lock-null resource<br> |
|
289 |
* Value : Vector of lock-null resource which are members of the collection. |
|
290 |
* Each element of the Vector is the path associated with the lock-null |
|
291 |
* resource. |
|
292 |
*/ |
|
293 |
private Hashtable<String, Vector<String>> lockNullResources = new Hashtable<String, Vector<String>>(); |
|
294 |
|
|
295 |
/** |
|
296 |
* Vector of the heritable locks. |
|
297 |
* <p> |
|
298 |
* Key : path <br> |
|
299 |
* Value : LockInfo |
|
300 |
*/ |
|
301 |
private Vector<LockInfo> collectionLocks = new Vector<LockInfo>(); |
|
302 | 277 |
|
303 | 278 |
/** |
304 | 279 |
* Full range marker. |
... | ... | |
558 | 533 |
object = getService().getResourceAtPath(user.getId(), path, true); |
559 | 534 |
} catch (ObjectNotFoundException e) { |
560 | 535 |
exists = false; |
561 |
int slash = path.lastIndexOf('/'); |
|
562 |
if (slash != -1) { |
|
563 |
String parentPath = path.substring(0, slash); |
|
564 |
Vector currentLockNullResources = lockNullResources.get(parentPath); |
|
565 |
if (currentLockNullResources != null) { |
|
566 |
Enumeration lockNullResourcesList = currentLockNullResources.elements(); |
|
567 |
while (lockNullResourcesList.hasMoreElements()) { |
|
568 |
String lockNullPath = (String) lockNullResourcesList.nextElement(); |
|
569 |
if (lockNullPath.equals(path)) { |
|
570 |
resp.setStatus(WebdavStatus.SC_MULTI_STATUS); |
|
571 |
resp.setContentType("text/xml; charset=UTF-8"); |
|
572 |
// Create multistatus object |
|
573 |
XMLWriter generatedXML = new XMLWriter(resp.getWriter()); |
|
574 |
generatedXML.writeXMLHeader(); |
|
575 |
generatedXML.writeElement(null, "multistatus" + generateNamespaceDeclarations(), XMLWriter.OPENING); |
|
576 |
parseLockNullProperties(req, generatedXML, lockNullPath, type, properties); |
|
577 |
generatedXML.writeElement(null, "multistatus", XMLWriter.CLOSING); |
|
578 |
generatedXML.sendData(); |
|
579 |
return; |
|
580 |
} |
|
581 |
} |
|
582 |
} |
|
583 |
} |
|
584 | 536 |
} catch (RpcException e) { |
585 | 537 |
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path); |
586 | 538 |
return; |
... | ... | |
649 | 601 |
newPath += file.getName(); |
650 | 602 |
stackBelow.push(newPath); |
651 | 603 |
} |
652 |
// Displaying the lock-null resources present in that |
|
653 |
// collection |
|
654 |
String lockPath = currentPath; |
|
655 |
if (lockPath.endsWith("/")) |
|
656 |
lockPath = lockPath.substring(0, lockPath.length() - 1); |
|
657 |
Vector currentLockNullResources = lockNullResources.get(lockPath); |
|
658 |
if (currentLockNullResources != null) { |
|
659 |
Enumeration lockNullResourcesList = currentLockNullResources.elements(); |
|
660 |
while (lockNullResourcesList.hasMoreElements()) { |
|
661 |
String lockNullPath = (String) lockNullResourcesList.nextElement(); |
|
662 |
parseLockNullProperties(req, generatedXML, lockNullPath, type, properties); |
|
663 |
} |
|
664 |
} |
|
665 | 604 |
} |
666 | 605 |
if (stack.isEmpty()) { |
667 | 606 |
depth--; |
... | ... | |
826 | 765 |
} else |
827 | 766 |
resp.sendError(HttpServletResponse.SC_CONFLICT); |
828 | 767 |
|
829 |
// Removing any lock-null resource which would be present. |
|
830 |
lockNullResources.remove(path); |
|
831 | 768 |
} |
832 | 769 |
|
833 | 770 |
@Override |
... | ... | |
854 | 791 |
* @param resp the HTTP response |
855 | 792 |
* @throws IOException if an error occurs while sending the response |
856 | 793 |
*/ |
857 |
private void doUnlock(HttpServletRequest req, HttpServletResponse resp) throws IOException { |
|
858 |
if (isLocked(req)) { |
|
859 |
resp.sendError(WebdavStatus.SC_LOCKED); |
|
860 |
return; |
|
861 |
} |
|
862 |
String path = getRelativePath(req); |
|
863 |
String lockTokenHeader = req.getHeader("Lock-Token"); |
|
864 |
if (lockTokenHeader == null) |
|
865 |
lockTokenHeader = ""; |
|
866 |
|
|
867 |
// Checking resource locks |
|
868 |
LockInfo lock = resourceLocks.get(path); |
|
869 |
Enumeration tokenList = null; |
|
870 |
if (lock != null) { |
|
871 |
// At least one of the tokens of the locks must have been given |
|
872 |
tokenList = lock.tokens.elements(); |
|
873 |
while (tokenList.hasMoreElements()) { |
|
874 |
String token = (String) tokenList.nextElement(); |
|
875 |
if (lockTokenHeader.indexOf(token) != -1) |
|
876 |
lock.tokens.removeElement(token); |
|
877 |
} |
|
878 |
if (lock.tokens.isEmpty()) { |
|
879 |
resourceLocks.remove(path); |
|
880 |
// Removing any lock-null resource which would be present |
|
881 |
lockNullResources.remove(path); |
|
882 |
} |
|
883 |
} |
|
884 |
// Checking inheritable collection locks |
|
885 |
Enumeration collectionLocksList = collectionLocks.elements(); |
|
886 |
while (collectionLocksList.hasMoreElements()) { |
|
887 |
lock = (LockInfo) collectionLocksList.nextElement(); |
|
888 |
if (path.equals(lock.path)) { |
|
889 |
tokenList = lock.tokens.elements(); |
|
890 |
while (tokenList.hasMoreElements()) { |
|
891 |
String token = (String) tokenList.nextElement(); |
|
892 |
if (lockTokenHeader.indexOf(token) != -1) { |
|
893 |
lock.tokens.removeElement(token); |
|
894 |
break; |
|
895 |
} |
|
896 |
} |
|
897 |
if (lock.tokens.isEmpty()) { |
|
898 |
collectionLocks.removeElement(lock); |
|
899 |
// Removing any lock-null resource which would be present |
|
900 |
lockNullResources.remove(path); |
|
901 |
} |
|
902 |
} |
|
903 |
} |
|
794 |
private void doUnlock(@SuppressWarnings("unused") HttpServletRequest req, HttpServletResponse resp) throws IOException { |
|
904 | 795 |
resp.setStatus(WebdavStatus.SC_NO_CONTENT); |
905 | 796 |
} |
906 | 797 |
|
... | ... | |
913 | 804 |
* @throws ServletException |
914 | 805 |
*/ |
915 | 806 |
private void doLock(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { |
916 |
if (isLocked(req)) { |
|
917 |
resp.sendError(WebdavStatus.SC_LOCKED); |
|
918 |
return; |
|
919 |
} |
|
920 |
|
|
921 | 807 |
LockInfo lock = new LockInfo(); |
922 | 808 |
// Parsing lock request |
923 | 809 |
|
... | ... | |
1085 | 971 |
return; |
1086 | 972 |
} |
1087 | 973 |
|
1088 |
Enumeration locksList = null; |
|
1089 | 974 |
if (lockRequestType == LOCK_CREATION) { |
1090 | 975 |
// Generating lock id |
1091 | 976 |
String lockTokenStr = req.getServletPath() + "-" + lock.type + "-" + lock.scope + "-" + req.getUserPrincipal() + "-" + lock.depth + "-" + lock.owner + "-" + lock.tokens + "-" + lock.expiresAt + "-" + System.currentTimeMillis() + "-" + secret; |
1092 | 977 |
String lockToken = md5Encoder.encode(md5Helper.digest(lockTokenStr.getBytes())); |
1093 | 978 |
|
1094 |
if (exists && object instanceof FolderDTO && lock.depth == INFINITY) { |
|
1095 |
|
|
979 |
if (exists && object instanceof FolderDTO && lock.depth == INFINITY) |
|
1096 | 980 |
// Locking a collection (and all its member resources) |
1097 |
|
|
1098 |
// Checking if a child resource of this collection is |
|
1099 |
// already locked |
|
1100 |
Vector<String> lockPaths = new Vector<String>(); |
|
1101 |
locksList = collectionLocks.elements(); |
|
1102 |
while (locksList.hasMoreElements()) { |
|
1103 |
LockInfo currentLock = (LockInfo) locksList.nextElement(); |
|
1104 |
if (currentLock.hasExpired()) { |
|
1105 |
resourceLocks.remove(currentLock.path); |
|
1106 |
continue; |
|
1107 |
} |
|
1108 |
if (currentLock.path.startsWith(lock.path) && (currentLock.isExclusive() || lock.isExclusive())) |
|
1109 |
// A child collection of this collection is locked |
|
1110 |
lockPaths.addElement(currentLock.path); |
|
1111 |
} |
|
1112 |
locksList = resourceLocks.elements(); |
|
1113 |
while (locksList.hasMoreElements()) { |
|
1114 |
LockInfo currentLock = (LockInfo) locksList.nextElement(); |
|
1115 |
if (currentLock.hasExpired()) { |
|
1116 |
resourceLocks.remove(currentLock.path); |
|
1117 |
continue; |
|
1118 |
} |
|
1119 |
if (currentLock.path.startsWith(lock.path) && (currentLock.isExclusive() || lock.isExclusive())) |
|
1120 |
// A child resource of this collection is locked |
|
1121 |
lockPaths.addElement(currentLock.path); |
|
1122 |
} |
|
1123 |
|
|
1124 |
if (!lockPaths.isEmpty()) { |
|
1125 |
// One of the child paths was locked |
|
1126 |
// We generate a multistatus error report |
|
1127 |
Enumeration lockPathsList = lockPaths.elements(); |
|
1128 |
resp.setStatus(WebdavStatus.SC_CONFLICT); |
|
1129 |
XMLWriter generatedXML = new XMLWriter(); |
|
1130 |
generatedXML.writeXMLHeader(); |
|
1131 |
|
|
1132 |
generatedXML.writeElement(null, "multistatus" + generateNamespaceDeclarations(), XMLWriter.OPENING); |
|
1133 |
|
|
1134 |
while (lockPathsList.hasMoreElements()) { |
|
1135 |
generatedXML.writeElement(null, "response", XMLWriter.OPENING); |
|
1136 |
generatedXML.writeElement(null, "href", XMLWriter.OPENING); |
|
1137 |
generatedXML.writeText((String) lockPathsList.nextElement()); |
|
1138 |
generatedXML.writeElement(null, "href", XMLWriter.CLOSING); |
|
1139 |
generatedXML.writeElement(null, "status", XMLWriter.OPENING); |
|
1140 |
generatedXML.writeText("HTTP/1.1 " + WebdavStatus.SC_LOCKED + " " + WebdavStatus.getStatusText(WebdavStatus.SC_LOCKED)); |
|
1141 |
generatedXML.writeElement(null, "status", XMLWriter.CLOSING); |
|
1142 |
generatedXML.writeElement(null, "response", XMLWriter.CLOSING); |
|
1143 |
} |
|
1144 |
|
|
1145 |
generatedXML.writeElement(null, "multistatus", XMLWriter.CLOSING); |
|
1146 |
|
|
1147 |
Writer writer = resp.getWriter(); |
|
1148 |
writer.write(generatedXML.toString()); |
|
1149 |
writer.close(); |
|
1150 |
return; |
|
1151 |
} |
|
1152 |
|
|
1153 |
boolean addLock = true; |
|
1154 |
// Checking if there is already a shared lock on this path |
|
1155 |
locksList = collectionLocks.elements(); |
|
1156 |
while (locksList.hasMoreElements()) { |
|
1157 |
LockInfo currentLock = (LockInfo) locksList.nextElement(); |
|
1158 |
if (currentLock.path.equals(lock.path)) { |
|
1159 |
if (currentLock.isExclusive()) { |
|
1160 |
resp.sendError(WebdavStatus.SC_LOCKED); |
|
1161 |
return; |
|
1162 |
} else if (lock.isExclusive()) { |
|
1163 |
resp.sendError(WebdavStatus.SC_LOCKED); |
|
1164 |
return; |
|
1165 |
} |
|
1166 |
currentLock.tokens.addElement(lockToken); |
|
1167 |
lock = currentLock; |
|
1168 |
addLock = false; |
|
1169 |
} |
|
1170 |
} |
|
1171 |
if (addLock) { |
|
1172 |
lock.tokens.addElement(lockToken); |
|
1173 |
collectionLocks.addElement(lock); |
|
1174 |
} |
|
1175 |
} else { |
|
981 |
lock.tokens.addElement(lockToken); |
|
982 |
else { |
|
1176 | 983 |
// Locking a single resource |
984 |
lock.tokens.addElement(lockToken); |
|
985 |
// Add the Lock-Token header as by RFC 2518 8.10.1 |
|
986 |
// - only do this for newly created locks |
|
987 |
resp.addHeader("Lock-Token", "<opaquelocktoken:" + lockToken + ">"); |
|
1177 | 988 |
|
1178 |
// Retrieving an already existing lock on that resource |
|
1179 |
LockInfo presentLock = resourceLocks.get(lock.path); |
|
1180 |
if (presentLock != null) { |
|
1181 |
if (presentLock.isExclusive() || lock.isExclusive()) { |
|
1182 |
// If either lock is exclusive, the lock can't be |
|
1183 |
// granted. |
|
1184 |
resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED); |
|
1185 |
return; |
|
1186 |
} else { |
|
1187 |
presentLock.tokens.addElement(lockToken); |
|
1188 |
lock = presentLock; |
|
1189 |
} |
|
1190 |
|
|
1191 |
} else { |
|
1192 |
lock.tokens.addElement(lockToken); |
|
1193 |
resourceLocks.put(lock.path, lock); |
|
1194 |
// Checking if a resource exists at this path |
|
1195 |
exists = true; |
|
1196 |
try { |
|
1197 |
object = getService().getResourceAtPath(user.getId(), path, true); |
|
1198 |
} catch (ObjectNotFoundException e) { |
|
1199 |
exists = false; |
|
1200 |
} catch (RpcException e) { |
|
1201 |
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path); |
|
1202 |
return; |
|
1203 |
} |
|
1204 |
if (!exists) { |
|
1205 |
// "Creating" a lock-null resource |
|
1206 |
int slash = lock.path.lastIndexOf('/'); |
|
1207 |
String parentPath = lock.path.substring(0, slash); |
|
1208 |
Vector<String> lockNulls = lockNullResources.get(parentPath); |
|
1209 |
if (lockNulls == null) { |
|
1210 |
lockNulls = new Vector<String>(); |
|
1211 |
lockNullResources.put(parentPath, lockNulls); |
|
1212 |
} |
|
1213 |
lockNulls.addElement(lock.path); |
|
1214 |
} |
|
1215 |
// Add the Lock-Token header as by RFC 2518 8.10.1 |
|
1216 |
// - only do this for newly created locks |
|
1217 |
resp.addHeader("Lock-Token", "<opaquelocktoken:" + lockToken + ">"); |
|
1218 |
} |
|
1219 | 989 |
} |
1220 | 990 |
} |
1221 | 991 |
|
1222 | 992 |
if (lockRequestType == LOCK_REFRESH) { |
1223 |
String ifHeader = req.getHeader("If"); |
|
1224 |
if (ifHeader == null) |
|
1225 |
ifHeader = ""; |
|
1226 |
// Checking resource locks |
|
1227 |
LockInfo toRenew = resourceLocks.get(path); |
|
1228 |
Enumeration tokenList = null; |
|
1229 |
if (lock != null) { |
|
1230 |
// At least one of the tokens of the locks must have been given |
|
1231 |
tokenList = toRenew.tokens.elements(); |
|
1232 |
while (tokenList.hasMoreElements()) { |
|
1233 |
String token = (String) tokenList.nextElement(); |
|
1234 |
if (ifHeader.indexOf(token) != -1) { |
|
1235 |
toRenew.expiresAt = lock.expiresAt; |
|
1236 |
lock = toRenew; |
|
1237 |
} |
|
1238 |
} |
|
1239 |
} |
|
1240 |
// Checking inheritable collection locks |
|
1241 |
Enumeration collectionLocksList = collectionLocks.elements(); |
|
1242 |
while (collectionLocksList.hasMoreElements()) { |
|
1243 |
toRenew = (LockInfo) collectionLocksList.nextElement(); |
|
1244 |
if (path.equals(toRenew.path)) { |
|
1245 |
tokenList = toRenew.tokens.elements(); |
|
1246 |
while (tokenList.hasMoreElements()) { |
|
1247 |
String token = (String) tokenList.nextElement(); |
|
1248 |
if (ifHeader.indexOf(token) != -1) { |
|
1249 |
toRenew.expiresAt = lock.expiresAt; |
|
1250 |
lock = toRenew; |
|
1251 |
} |
|
1252 |
} |
|
1253 |
} |
|
1254 |
} |
|
993 |
|
|
1255 | 994 |
} |
995 |
|
|
1256 | 996 |
// Set the status, then generate the XML response containing |
1257 | 997 |
// the lock information. |
1258 | 998 |
XMLWriter generatedXML = new XMLWriter(); |
... | ... | |
1397 | 1137 |
return; |
1398 | 1138 |
} |
1399 | 1139 |
resp.setStatus(WebdavStatus.SC_CREATED); |
1400 |
// Removing any lock-null resource which would be present |
|
1401 |
lockNullResources.remove(path); |
|
1402 | 1140 |
} |
1403 | 1141 |
|
1404 | 1142 |
/** |
... | ... | |
1514 | 1252 |
* @param propertiesVector If the propfind type is find properties by name, |
1515 | 1253 |
* then this Vector contains those properties |
1516 | 1254 |
*/ |
1255 |
@SuppressWarnings("unused") |
|
1517 | 1256 |
private void parseLockNullProperties(HttpServletRequest req, XMLWriter generatedXML, String path, int type, Vector propertiesVector) { |
1518 |
|
|
1519 |
// Exclude any resource in the /WEB-INF and /META-INF subdirectories |
|
1520 |
// (the "toUpperCase()" avoids problems on Windows systems) |
|
1521 |
if (path.toUpperCase().startsWith("/WEB-INF") || path.toUpperCase().startsWith("/META-INF")) |
|
1522 |
return; |
|
1523 |
|
|
1524 |
// Retrieving the lock associated with the lock-null resource |
|
1525 |
LockInfo lock = resourceLocks.get(path); |
|
1526 |
|
|
1527 |
if (lock == null) |
|
1528 |
return; |
|
1529 |
|
|
1530 |
generatedXML.writeElement(null, "response", XMLWriter.OPENING); |
|
1531 |
String status = new String("HTTP/1.1 " + WebdavStatus.SC_OK + " " + WebdavStatus.getStatusText(WebdavStatus.SC_OK)); |
|
1532 |
|
|
1533 |
// Generating href element |
|
1534 |
generatedXML.writeElement(null, "href", XMLWriter.OPENING); |
|
1535 |
|
|
1536 |
String absoluteUri = req.getRequestURI(); |
|
1537 |
String relativePath = getRelativePath(req); |
|
1538 |
String toAppend = path.substring(relativePath.length()); |
|
1539 |
if (!toAppend.startsWith("/")) |
|
1540 |
toAppend = "/" + toAppend; |
|
1541 |
|
|
1542 |
generatedXML.writeText(rewriteUrl(RequestUtil.normalize(absoluteUri + toAppend))); |
|
1543 |
|
|
1544 |
generatedXML.writeElement(null, "href", XMLWriter.CLOSING); |
|
1545 |
|
|
1546 |
String resourceName = path; |
|
1547 |
int lastSlash = path.lastIndexOf('/'); |
|
1548 |
if (lastSlash != -1) |
|
1549 |
resourceName = resourceName.substring(lastSlash + 1); |
|
1550 |
|
|
1551 |
switch (type) { |
|
1552 |
|
|
1553 |
case FIND_ALL_PROP: |
|
1554 |
|
|
1555 |
generatedXML.writeElement(null, "propstat", XMLWriter.OPENING); |
|
1556 |
generatedXML.writeElement(null, "prop", XMLWriter.OPENING); |
|
1557 |
|
|
1558 |
generatedXML.writeProperty(null, "creationdate", getISOCreationDate(lock.creationDate.getTime())); |
|
1559 |
generatedXML.writeElement(null, "displayname", XMLWriter.OPENING); |
|
1560 |
generatedXML.writeData(resourceName); |
|
1561 |
generatedXML.writeElement(null, "displayname", XMLWriter.CLOSING); |
|
1562 |
generatedXML.writeProperty(null, "getlastmodified", FastHttpDateFormat.formatDate(lock.creationDate.getTime(), null)); |
|
1563 |
generatedXML.writeProperty(null, "getcontentlength", String.valueOf(0)); |
|
1564 |
generatedXML.writeProperty(null, "getcontenttype", ""); |
|
1565 |
generatedXML.writeProperty(null, "getetag", ""); |
|
1566 |
generatedXML.writeElement(null, "resourcetype", XMLWriter.OPENING); |
|
1567 |
generatedXML.writeElement(null, "lock-null", XMLWriter.NO_CONTENT); |
|
1568 |
generatedXML.writeElement(null, "resourcetype", XMLWriter.CLOSING); |
|
1569 |
|
|
1570 |
generatedXML.writeProperty(null, "source", ""); |
|
1571 |
|
|
1572 |
String supportedLocks = "<lockentry>" + "<lockscope><exclusive/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>" + "<lockentry>" + "<lockscope><shared/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>"; |
|
1573 |
generatedXML.writeElement(null, "supportedlock", XMLWriter.OPENING); |
|
1574 |
generatedXML.writeText(supportedLocks); |
|
1575 |
generatedXML.writeElement(null, "supportedlock", XMLWriter.CLOSING); |
|
1576 |
|
|
1577 |
generateLockDiscovery(path, generatedXML); |
|
1578 |
|
|
1579 |
generatedXML.writeElement(null, "prop", XMLWriter.CLOSING); |
|
1580 |
generatedXML.writeElement(null, "status", XMLWriter.OPENING); |
|
1581 |
generatedXML.writeText(status); |
|
1582 |
generatedXML.writeElement(null, "status", XMLWriter.CLOSING); |
|
1583 |
generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING); |
|
1584 |
|
|
1585 |
break; |
|
1586 |
|
|
1587 |
case FIND_PROPERTY_NAMES: |
|
1588 |
|
|
1589 |
generatedXML.writeElement(null, "propstat", XMLWriter.OPENING); |
|
1590 |
generatedXML.writeElement(null, "prop", XMLWriter.OPENING); |
|
1591 |
|
|
1592 |
generatedXML.writeElement(null, "creationdate", XMLWriter.NO_CONTENT); |
|
1593 |
generatedXML.writeElement(null, "displayname", XMLWriter.NO_CONTENT); |
|
1594 |
generatedXML.writeElement(null, "getcontentlanguage", XMLWriter.NO_CONTENT); |
|
1595 |
generatedXML.writeElement(null, "getcontentlength", XMLWriter.NO_CONTENT); |
|
1596 |
generatedXML.writeElement(null, "getcontenttype", XMLWriter.NO_CONTENT); |
|
1597 |
generatedXML.writeElement(null, "getetag", XMLWriter.NO_CONTENT); |
|
1598 |
generatedXML.writeElement(null, "getlastmodified", XMLWriter.NO_CONTENT); |
|
1599 |
generatedXML.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT); |
|
1600 |
generatedXML.writeElement(null, "source", XMLWriter.NO_CONTENT); |
|
1601 |
generatedXML.writeElement(null, "lockdiscovery", XMLWriter.NO_CONTENT); |
|
1602 |
|
|
1603 |
generatedXML.writeElement(null, "prop", XMLWriter.CLOSING); |
|
1604 |
generatedXML.writeElement(null, "status", XMLWriter.OPENING); |
|
1605 |
generatedXML.writeText(status); |
|
1606 |
generatedXML.writeElement(null, "status", XMLWriter.CLOSING); |
|
1607 |
generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING); |
|
1608 |
|
|
1609 |
break; |
|
1610 |
|
|
1611 |
case FIND_BY_PROPERTY: |
|
1612 |
|
|
1613 |
Vector<String> propertiesNotFound = new Vector<String>(); |
|
1614 |
|
|
1615 |
// Parse the list of properties |
|
1616 |
|
|
1617 |
generatedXML.writeElement(null, "propstat", XMLWriter.OPENING); |
|
1618 |
generatedXML.writeElement(null, "prop", XMLWriter.OPENING); |
|
1619 |
|
|
1620 |
Enumeration properties = propertiesVector.elements(); |
|
1621 |
|
|
1622 |
while (properties.hasMoreElements()) { |
|
1623 |
|
|
1624 |
String property = (String) properties.nextElement(); |
|
1625 |
|
|
1626 |
if (property.equals("creationdate")) |
|
1627 |
generatedXML.writeProperty(null, "creationdate", getISOCreationDate(lock.creationDate.getTime())); |
|
1628 |
else if (property.equals("displayname")) { |
|
1629 |
generatedXML.writeElement(null, "displayname", XMLWriter.OPENING); |
|
1630 |
generatedXML.writeData(resourceName); |
|
1631 |
generatedXML.writeElement(null, "displayname", XMLWriter.CLOSING); |
|
1632 |
} else if (property.equals("getcontentlanguage")) |
|
1633 |
generatedXML.writeElement(null, "getcontentlanguage", XMLWriter.NO_CONTENT); |
|
1634 |
else if (property.equals("getcontentlength")) |
|
1635 |
generatedXML.writeProperty(null, "getcontentlength", String.valueOf(0)); |
|
1636 |
else if (property.equals("getcontenttype")) |
|
1637 |
generatedXML.writeProperty(null, "getcontenttype", ""); |
|
1638 |
else if (property.equals("getetag")) |
|
1639 |
generatedXML.writeProperty(null, "getetag", ""); |
|
1640 |
else if (property.equals("getlastmodified")) |
|
1641 |
generatedXML.writeProperty(null, "getlastmodified", FastHttpDateFormat.formatDate(lock.creationDate.getTime(), null)); |
|
1642 |
else if (property.equals("resourcetype")) { |
|
1643 |
generatedXML.writeElement(null, "resourcetype", XMLWriter.OPENING); |
|
1644 |
generatedXML.writeElement(null, "lock-null", XMLWriter.NO_CONTENT); |
|
1645 |
generatedXML.writeElement(null, "resourcetype", XMLWriter.CLOSING); |
|
1646 |
} else if (property.equals("source")) |
|
1647 |
generatedXML.writeProperty(null, "source", ""); |
|
1648 |
else if (property.equals("supportedlock")) { |
|
1649 |
supportedLocks = "<lockentry>" + "<lockscope><exclusive/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>" + "<lockentry>" + "<lockscope><shared/></lockscope>" + "<locktype><write/></locktype>" + "</lockentry>"; |
|
1650 |
generatedXML.writeElement(null, "supportedlock", XMLWriter.OPENING); |
|
1651 |
generatedXML.writeText(supportedLocks); |
|
1652 |
generatedXML.writeElement(null, "supportedlock", XMLWriter.CLOSING); |
|
1653 |
} else if (property.equals("lockdiscovery")) { |
|
1654 |
if (!generateLockDiscovery(path, generatedXML)) |
|
1655 |
propertiesNotFound.addElement(property); |
|
1656 |
} else |
|
1657 |
propertiesNotFound.addElement(property); |
|
1658 |
|
|
1659 |
} |
|
1660 |
|
|
1661 |
generatedXML.writeElement(null, "prop", XMLWriter.CLOSING); |
|
1662 |
generatedXML.writeElement(null, "status", XMLWriter.OPENING); |
|
1663 |
generatedXML.writeText(status); |
|
1664 |
generatedXML.writeElement(null, "status", XMLWriter.CLOSING); |
|
1665 |
generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING); |
|
1666 |
|
|
1667 |
Enumeration propertiesNotFoundList = propertiesNotFound.elements(); |
|
1668 |
|
|
1669 |
if (propertiesNotFoundList.hasMoreElements()) { |
|
1670 |
|
|
1671 |
status = new String("HTTP/1.1 " + WebdavStatus.SC_NOT_FOUND + " " + WebdavStatus.getStatusText(WebdavStatus.SC_NOT_FOUND)); |
|
1672 |
|
|
1673 |
generatedXML.writeElement(null, "propstat", XMLWriter.OPENING); |
|
1674 |
generatedXML.writeElement(null, "prop", XMLWriter.OPENING); |
|
1675 |
|
|
1676 |
while (propertiesNotFoundList.hasMoreElements()) |
|
1677 |
generatedXML.writeElement(null, (String) propertiesNotFoundList.nextElement(), XMLWriter.NO_CONTENT); |
|
1678 |
|
|
1679 |
generatedXML.writeElement(null, "prop", XMLWriter.CLOSING); |
|
1680 |
generatedXML.writeElement(null, "status", XMLWriter.OPENING); |
|
1681 |
generatedXML.writeText(status); |
|
1682 |
generatedXML.writeElement(null, "status", XMLWriter.CLOSING); |
|
1683 |
generatedXML.writeElement(null, "propstat", XMLWriter.CLOSING); |
|
1684 |
|
|
1685 |
} |
|
1686 |
|
|
1687 |
break; |
|
1688 |
|
|
1689 |
} |
|
1690 |
|
|
1691 |
generatedXML.writeElement(null, "response", XMLWriter.CLOSING); |
|
1692 |
|
|
1257 |
return; |
|
1693 | 1258 |
} |
1694 | 1259 |
|
1695 | 1260 |
/** |
... | ... | |
1953 | 1518 |
* @param generatedXML XML data to which the locks info will be appended |
1954 | 1519 |
* @return true if at least one lock was displayed |
1955 | 1520 |
*/ |
1956 |
private boolean generateLockDiscovery(String path, XMLWriter generatedXML) { |
|
1957 |
LockInfo resourceLock = resourceLocks.get(path); |
|
1958 |
Enumeration collectionLocksList = collectionLocks.elements(); |
|
1959 |
boolean wroteStart = false; |
|
1960 |
if (resourceLock != null) { |
|
1961 |
wroteStart = true; |
|
1962 |
generatedXML.writeElement(null, "lockdiscovery", XMLWriter.OPENING); |
|
1963 |
resourceLock.toXML(generatedXML); |
|
1964 |
} |
|
1965 |
|
|
1966 |
while (collectionLocksList.hasMoreElements()) { |
|
1967 |
LockInfo currentLock = (LockInfo) collectionLocksList.nextElement(); |
|
1968 |
if (path.startsWith(currentLock.path)) { |
|
1969 |
if (!wroteStart) { |
|
1970 |
wroteStart = true; |
|
1971 |
generatedXML.writeElement(null, "lockdiscovery", XMLWriter.OPENING); |
|
1972 |
} |
|
1973 |
currentLock.toXML(generatedXML); |
|
1974 |
} |
|
1975 |
} |
|
1976 |
|
|
1977 |
if (wroteStart) |
|
1978 |
generatedXML.writeElement(null, "lockdiscovery", XMLWriter.CLOSING); |
|
1979 |
else |
|
1521 |
@SuppressWarnings("unused") |
|
1522 |
private boolean generateLockDiscovery(String path, XMLWriter generatedXML) { |
|
1980 | 1523 |
return false; |
1981 |
|
|
1982 |
return true; |
|
1983 |
|
|
1984 | 1524 |
} |
1985 | 1525 |
|
1986 | 1526 |
/** |
... | ... | |
2063 | 1603 |
* token has been found for at least one of the non-shared locks |
2064 | 1604 |
* which are present on the resource). |
2065 | 1605 |
*/ |
2066 |
private boolean isLocked(HttpServletRequest req) { |
|
2067 |
String path = getRelativePath(req); |
|
2068 |
String ifHeader = req.getHeader("If"); |
|
2069 |
if (ifHeader == null) |
|
2070 |
ifHeader = ""; |
|
2071 |
String lockTokenHeader = req.getHeader("Lock-Token"); |
|
2072 |
if (lockTokenHeader == null) |
|
2073 |
lockTokenHeader = ""; |
|
2074 |
return isLocked(path, ifHeader + lockTokenHeader); |
|
1606 |
private boolean isLocked(@SuppressWarnings("unused") HttpServletRequest req) { |
|
1607 |
return false; |
|
2075 | 1608 |
} |
2076 | 1609 |
|
2077 | 1610 |
/** |
... | ... | |
2083 | 1616 |
* token has been found for at least one of the non-shared locks |
2084 | 1617 |
* which are present on the resource). |
2085 | 1618 |
*/ |
2086 |
private boolean isLocked(String path, String ifHeader) { |
|
2087 |
// Checking resource locks |
|
2088 |
LockInfo lock = resourceLocks.get(path); |
|
2089 |
Enumeration tokenList = null; |
|
2090 |
if (lock != null && lock.hasExpired()) |
|
2091 |
resourceLocks.remove(path); |
|
2092 |
else if (lock != null) { |
|
2093 |
// At least one of the tokens of the locks must have been given |
|
2094 |
tokenList = lock.tokens.elements(); |
|
2095 |
boolean tokenMatch = false; |
|
2096 |
while (tokenList.hasMoreElements()) { |
|
2097 |
String token = (String) tokenList.nextElement(); |
|
2098 |
if (ifHeader.indexOf(token) != -1) |
|
2099 |
tokenMatch = true; |
|
2100 |
} |
|
2101 |
if (!tokenMatch) |
|
2102 |
return true; |
|
2103 |
} |
|
2104 |
// Checking inheritable collection locks |
|
2105 |
Enumeration collectionLocksList = collectionLocks.elements(); |
|
2106 |
while (collectionLocksList.hasMoreElements()) { |
|
2107 |
lock = (LockInfo) collectionLocksList.nextElement(); |
|
2108 |
if (lock.hasExpired()) |
|
2109 |
collectionLocks.removeElement(lock); |
|
2110 |
else if (path.startsWith(lock.path)) { |
|
2111 |
tokenList = lock.tokens.elements(); |
|
2112 |
boolean tokenMatch = false; |
|
2113 |
while (tokenList.hasMoreElements()) { |
|
2114 |
String token = (String) tokenList.nextElement(); |
|
2115 |
if (ifHeader.indexOf(token) != -1) |
|
2116 |
tokenMatch = true; |
|
2117 |
} |
|
2118 |
if (!tokenMatch) |
|
2119 |
return true; |
|
2120 |
} |
|
2121 |
} |
|
1619 |
private boolean isLocked(@SuppressWarnings("unused") String path, @SuppressWarnings("unused") String ifHeader) { |
|
2122 | 1620 |
return false; |
2123 | 1621 |
} |
2124 | 1622 |
|
... | ... | |
3446 | 2944 |
sendReport(req, resp, errorList); |
3447 | 2945 |
return false; |
3448 | 2946 |
} |
3449 |
// Removing any lock-null resource which would be present at |
|
3450 |
// the destination path. |
|
3451 |
lockNullResources.remove(destinationPath); |
|
3452 | 2947 |
return true; |
3453 | 2948 |
} |
3454 | 2949 |
|
Also available in: Unified diff