Source Code Cross Referenced for DAVFrame.java in  » Web-Server » Jigsaw » org » w3c » jigsaw » webdav » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Jigsaw » org.w3c.jigsaw.webdav 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // DAVFrame.java
0002:        // $Id: DAVFrame.java,v 1.39 2007/02/09 22:45:42 ylafon Exp $
0003:        // (c) COPYRIGHT MIT, INRIA and Keio, 2000.
0004:        // Please first read the full copyright statement in file COPYRIGHT.html
0005:        package org.w3c.jigsaw.webdav;
0006:
0007:        import java.io.ByteArrayInputStream;
0008:        import java.io.ByteArrayOutputStream;
0009:        import java.io.FileInputStream;
0010:        import java.io.InputStream;
0011:        import java.io.IOException;
0012:
0013:        import java.net.MalformedURLException;
0014:        import java.net.URL;
0015:
0016:        import java.util.Date;
0017:        import java.util.Enumeration;
0018:        import java.util.Hashtable;
0019:        import java.util.ListIterator;
0020:        import java.util.LinkedList;
0021:        import java.util.Vector;
0022:
0023:        import org.xml.sax.SAXException;
0024:
0025:        import org.apache.xml.serialize.OutputFormat;
0026:        import org.apache.xml.serialize.XMLSerializer;
0027:
0028:        import org.w3c.dom.Document;
0029:        import org.w3c.dom.DOMException;
0030:        import org.w3c.dom.Element;
0031:        import org.w3c.dom.Node;
0032:
0033:        import org.w3c.jigsaw.auth.AuthFilter;
0034:
0035:        import org.w3c.jigsaw.frames.PostableFrame;
0036:
0037:        import org.w3c.jigsaw.http.HTTPException;
0038:        import org.w3c.jigsaw.http.Reply;
0039:        import org.w3c.jigsaw.http.Request;
0040:
0041:        import org.w3c.www.http.ContentLengthInputStream;
0042:
0043:        import org.w3c.tools.codec.Base64Decoder;
0044:        import org.w3c.tools.codec.Base64Encoder;
0045:        import org.w3c.tools.codec.Base64FormatException;
0046:
0047:        import org.w3c.tools.resources.Attribute;
0048:        import org.w3c.tools.resources.AttributeRegistry;
0049:        import org.w3c.tools.resources.ContainerResource;
0050:        import org.w3c.tools.resources.DateAttribute;
0051:        import org.w3c.tools.resources.DirectoryResource;
0052:        import org.w3c.tools.resources.FramedResource;
0053:        import org.w3c.tools.resources.IntegerAttribute;
0054:        import org.w3c.tools.resources.InvalidResourceException;
0055:        import org.w3c.tools.resources.LookupResult;
0056:        import org.w3c.tools.resources.LookupState;
0057:        import org.w3c.tools.resources.ProtocolException;
0058:        import org.w3c.tools.resources.PropertiesAttribute;
0059:        import org.w3c.tools.resources.RequestInterface;
0060:        import org.w3c.tools.resources.ReplyInterface;
0061:        import org.w3c.tools.resources.Resource;
0062:        import org.w3c.tools.resources.ResourceException;
0063:        import org.w3c.tools.resources.ResourceFrame;
0064:        import org.w3c.tools.resources.ResourceReference;
0065:        import org.w3c.tools.resources.ServerInterface;
0066:        import org.w3c.tools.resources.StringAttribute;
0067:
0068:        import org.w3c.util.ArrayDictionary;
0069:        import org.w3c.util.DateParser;
0070:        import org.w3c.util.InvalidDateException;
0071:        import org.w3c.util.ObservableProperties;
0072:        import org.w3c.util.URLUtils;
0073:
0074:        import org.w3c.www.http.HeaderDescription;
0075:        import org.w3c.www.http.HeaderValue;
0076:        import org.w3c.www.http.HTTP;
0077:        import org.w3c.www.http.HttpDate;
0078:        import org.w3c.www.http.HttpEntityTag;
0079:        import org.w3c.www.http.HttpFactory;
0080:        import org.w3c.www.http.HttpInvalidValueException;
0081:        import org.w3c.www.http.HttpMimeType;
0082:        import org.w3c.www.http.HttpMessage;
0083:        import org.w3c.www.http.HttpReplyMessage;
0084:        import org.w3c.www.http.HttpRequestMessage;
0085:        import org.w3c.www.http.HttpTokenList;
0086:
0087:        import org.w3c.www.mime.MimeType;
0088:        import org.w3c.www.mime.MimeTypeFormatException;
0089:
0090:        import org.w3c.www.webdav.WEBDAV;
0091:        import org.w3c.www.webdav.DAVEntityTag;
0092:        import org.w3c.www.webdav.DAVIf;
0093:        import org.w3c.www.webdav.DAVParser;
0094:        import org.w3c.www.webdav.DAVStateToken;
0095:
0096:        import org.w3c.www.webdav.xml.DAVBody;
0097:        import org.w3c.www.webdav.xml.DAVFactory;
0098:        import org.w3c.www.webdav.xml.DAVLockInfo;
0099:        import org.w3c.www.webdav.xml.DAVMultiStatus;
0100:        import org.w3c.www.webdav.xml.DAVNode;
0101:        import org.w3c.www.webdav.xml.DAVPropAction;
0102:        import org.w3c.www.webdav.xml.DAVPropertyBehavior;
0103:        import org.w3c.www.webdav.xml.DAVPropFind;
0104:        import org.w3c.www.webdav.xml.DAVPropStat;
0105:        import org.w3c.www.webdav.xml.DAVProperties;
0106:        import org.w3c.www.webdav.xml.DAVPropertyUpdate;
0107:        import org.w3c.www.webdav.xml.DAVResponse;
0108:
0109:        /**
0110:         * @version $Revision: 1.39 $
0111:         * @author  Benoît Mahé (bmahe@w3.org)
0112:         */
0113:        public class DAVFrame extends PostableFrame {
0114:
0115:            public static final boolean debug = false;
0116:
0117:            public static final boolean debugxml = false;
0118:
0119:            /**
0120:             * Condition check return code - Condition existed and succeeded.
0121:             * And lock has been checked
0122:             */
0123:            public static final int COND_OK_LOCK = 3;
0124:
0125:            /**
0126:             * Cached mime type
0127:             */
0128:            protected static HttpMimeType xmlcontenttype = null;
0129:            protected static HttpMimeType collectioncontenttype = null;
0130:
0131:            protected static boolean isReadOnly(String propname) {
0132:                return (propname.equals(DAVNode.CREATIONDATE_NODE)
0133:                        || propname.equals(DAVNode.GETCONTENTLENGTH_NODE)
0134:                        || propname.equals(DAVNode.GETETAG_NODE) || propname
0135:                        .equals(DAVNode.GETLASTMODIFIED_NODE));
0136:            }
0137:
0138:            protected static boolean acceptRedirect(DAVRequest request) {
0139:                String method = request.getMethod();
0140:                return !(method.equals("PROPPATCH")
0141:                        || method.equals("PROPFIND") || method.equals("COPY")
0142:                        || method.equals("MOVE") || method.equals("DELETE")
0143:                        || method.equals("LOCK") || method.equals("UNLOCK"));
0144:            }
0145:
0146:            /**
0147:             * The DAVManager we use.
0148:             */
0149:            protected org.w3c.www.protocol.webdav.DAVManager manager = null;
0150:
0151:            /**
0152:             * Name ot the state to hold the remaining path (used with MKCOL)
0153:             */
0154:            public final static String REMAINING_PATH = "org.w3c.jigsaw.webdav.rpath";
0155:
0156:            public final static String LOCK_USERNAME = "org.w3c.jigsaw.webdav.user";
0157:            public final static String LOCK_TOKEN = "org.w3c.jigsaw.webdav.token";
0158:            public final static String LOCK_OWNER = "org.w3c.jigsaw.webdav.owner";
0159:            public final static String LOCK_EXPIRE = "org.w3c.jigsaw.webdav.expire";
0160:            public final static String LOCK_TIMEOUT = "org.w3c.jigsaw.webdav.timeout";
0161:
0162:            public final static String LOCKED_REREFENCE = "org.w3c.jigsaw.webdav.reference";
0163:
0164:            public final static Long DEFAULT_LOCK_TIMEOUT = new Long(
0165:                    24 * 60 * 60 * 1000); // 1 day
0166:
0167:            public final static Long MAX_LOCK_TIMEOUT = new Long(7 * 24 * 60
0168:                    * 60 * 1000); // 1 week
0169:
0170:            /**
0171:             * Attribute index - The index for the creation date attribute.
0172:             */
0173:            protected static int ATTR_CREATION_DATE = -1;
0174:
0175:            /**
0176:             * Attribute index - The index for the dead properties
0177:             */
0178:            protected static int ATTR_DEAD_PROPERTIES = -1;
0179:
0180:            /**
0181:             * Attribute index - The index for the lock token
0182:             */
0183:            protected static int ATTR_LOCK_TOKEN = -1;
0184:
0185:            /**
0186:             * Attribute index - The index for the lock token
0187:             */
0188:            protected static int ATTR_LOCK_TIMEOUT = -1;
0189:
0190:            /**
0191:             * Attribute index - The index for the lock date
0192:             */
0193:            protected static int ATTR_LOCK_DATE = -1;
0194:
0195:            /**
0196:             * Attribute index - The index for the lock depth
0197:             */
0198:            protected static int ATTR_LOCK_DEPTH = -1;
0199:
0200:            /**
0201:             * Attribute index - The index for the lock owner
0202:             */
0203:            protected static int ATTR_LOCK_OWNER = -1;
0204:
0205:            /**
0206:             * Attribute index - The index for the lock username
0207:             */
0208:            protected static int ATTR_LOCK_USERNAME = -1;
0209:
0210:            static {
0211:                Class cls = null;
0212:                // Get a pointer to our own class:
0213:                try {
0214:                    cls = Class.forName("org.w3c.jigsaw.webdav.DAVFrame");
0215:                } catch (Exception ex) {
0216:                    ex.printStackTrace();
0217:                    System.exit(1);
0218:                }
0219:                // Our creation date
0220:                Attribute a = new DateAttribute("creation-date", null,
0221:                        Attribute.COMPUTED);
0222:                ATTR_CREATION_DATE = AttributeRegistry
0223:                        .registerAttribute(cls, a);
0224:                // Our creation date
0225:                a = new PropertiesAttribute("dead-properties", null,
0226:                        Attribute.COMPUTED);
0227:                ATTR_DEAD_PROPERTIES = AttributeRegistry.registerAttribute(cls,
0228:                        a);
0229:                // Our lock token (if any)
0230:                a = new StringAttribute("lock-token", null, Attribute.COMPUTED);
0231:                ATTR_LOCK_TOKEN = AttributeRegistry.registerAttribute(cls, a);
0232:                // Our timeout token (if any)
0233:                a = new DateAttribute("lock-timeout", null, Attribute.COMPUTED);
0234:                ATTR_LOCK_TIMEOUT = AttributeRegistry.registerAttribute(cls, a);
0235:                // Our lock token date
0236:                a = new DateAttribute("lock-date", null, Attribute.COMPUTED);
0237:                ATTR_LOCK_DATE = AttributeRegistry.registerAttribute(cls, a);
0238:                // Our expire token (if any)
0239:                a = new IntegerAttribute("lock-depth", null, Attribute.COMPUTED);
0240:                ATTR_LOCK_DEPTH = AttributeRegistry.registerAttribute(cls, a);
0241:                // Our lock owner
0242:                a = new StringAttribute("lock-owner", null, Attribute.COMPUTED);
0243:                ATTR_LOCK_OWNER = AttributeRegistry.registerAttribute(cls, a);
0244:                // Our lock owner
0245:                a = new StringAttribute("lock-username", null,
0246:                        Attribute.COMPUTED);
0247:                ATTR_LOCK_USERNAME = AttributeRegistry
0248:                        .registerAttribute(cls, a);
0249:
0250:                // xml content type
0251:                try {
0252:                    MimeType type = new MimeType("text/xml");
0253:                    type.addParameter("charset", WEBDAV.ENCODING);
0254:                    xmlcontenttype = HttpFactory.makeMimeType(type);
0255:                    type = new MimeType("httpd/unix-directory");
0256:                    type.addParameter("charset", WEBDAV.ENCODING);
0257:                    collectioncontenttype = HttpFactory.makeMimeType(type);
0258:                } catch (MimeTypeFormatException ex) {
0259:                    ex.printStackTrace();
0260:                    System.exit(1);
0261:                }
0262:            }
0263:
0264:            public boolean isCollection() {
0265:                return (dresource != null);
0266:            }
0267:
0268:            /**
0269:             * Get this resource creation date
0270:             * @return A long giving the creation date or -1 if undefined.
0271:             */
0272:            public long getCreationDate() {
0273:                return getLong(ATTR_CREATION_DATE, (long) -1);
0274:            }
0275:
0276:            protected void updateLockDate(DAVRequest request) {
0277:                if (checkLockOwner(request)) {
0278:                    if (debug) {
0279:                        System.out.println(">>> update lock date");
0280:                    }
0281:                    setValue(ATTR_LOCK_DATE, new Long(System
0282:                            .currentTimeMillis()));
0283:                }
0284:            }
0285:
0286:            /**
0287:             * Get the lock token expiration date
0288:             * @return A long giving the expiration date or -1 if undefined.
0289:             */
0290:            protected long getTokenExpirationDate(DAVRequest request) {
0291:                long timeout = getLong(ATTR_LOCK_TIMEOUT, (long) -1);
0292:                long lockdate = getLong(ATTR_LOCK_DATE, (long) -1);
0293:                if ((lockdate != -1) && (timeout != -1)) {
0294:                    return lockdate + timeout;
0295:                } else if (request != null) {
0296:                    Long expire = (Long) request.getState(LOCK_EXPIRE);
0297:                    if (expire != null) {
0298:                        return expire.longValue();
0299:                    }
0300:                }
0301:                return -1;
0302:            }
0303:
0304:            /**
0305:             * Get the lock token 
0306:             * @return A String instance or null
0307:             */
0308:            protected String getCurrentLockToken(DAVRequest request) {
0309:                String token = getString(ATTR_LOCK_TOKEN, null);
0310:                if ((token == null) && (request != null)) {
0311:                    token = (String) request.getState(LOCK_TOKEN);
0312:                }
0313:                return token;
0314:            }
0315:
0316:            protected long getCurrentLockTimeout(DAVRequest request) {
0317:                long timeout = getLong(ATTR_LOCK_TIMEOUT, (long) -1);
0318:                if (timeout == -1) {
0319:                    Long l = (Long) request.getState(LOCK_TIMEOUT);
0320:                    if (l != null) {
0321:                        return l.longValue();
0322:                    } else {
0323:                        return DEFAULT_LOCK_TIMEOUT.longValue();
0324:                    }
0325:                } else {
0326:                    return timeout;
0327:                }
0328:            }
0329:
0330:            protected Node ownerNode = null;
0331:
0332:            /**
0333:             * Get the lock owner
0334:             * @return A String instance or null
0335:             */
0336:            protected Node getCurrentLockOwner(DAVRequest request) {
0337:                if (ownerNode == null) {
0338:                    String owner = getString(ATTR_LOCK_OWNER, null);
0339:                    if (owner != null) {
0340:                        Base64Decoder decoder = new Base64Decoder(owner);
0341:                        try {
0342:                            String decoded = decoder.processString();
0343:                            ByteArrayInputStream in = new ByteArrayInputStream(
0344:                                    decoded.getBytes());
0345:                            Document doc = DAVBody.getDocument(in, null);
0346:                            ownerNode = doc.getDocumentElement();
0347:                        } catch (Exception ex) {
0348:                            ex.printStackTrace();
0349:                        }
0350:                    } else if ((owner == null) && (request != null)) {
0351:                        return (Node) request.getState(LOCK_OWNER);
0352:                    }
0353:                }
0354:                return ownerNode;
0355:            }
0356:
0357:            /**
0358:             * Set the lock Owner
0359:             */
0360:            protected void setLockOwner(Node owner) {
0361:                ownerNode = owner;
0362:                saveLockOwner();
0363:            }
0364:
0365:            private synchronized void saveLockOwner() {
0366:                if (ownerNode != null) {
0367:                    Document doc = DAVBody.createDocument(DAVNode.OWNER_NODE);
0368:                    DAVNode.exportChildren(doc, doc.getDocumentElement(),
0369:                            ownerNode, true);
0370:                    ByteArrayOutputStream out = new ByteArrayOutputStream();
0371:                    OutputFormat format = new OutputFormat(doc,
0372:                            WEBDAV.ENCODING, true);
0373:                    format.setOmitXMLDeclaration(false);
0374:                    format.setPreserveSpace(true);
0375:                    XMLSerializer serializer = new XMLSerializer(out, format);
0376:                    try {
0377:                        serializer.serialize(doc);
0378:                        if (debug)
0379:                            System.out.println("["
0380:                                    + out.toString(WEBDAV.ENCODING) + "]");
0381:                        Base64Encoder encoder = new Base64Encoder(out
0382:                                .toString(WEBDAV.ENCODING));
0383:                        setValue(ATTR_LOCK_OWNER, encoder.processString());
0384:                    } catch (IOException ex) {
0385:                        ex.printStackTrace();
0386:                    }
0387:                }
0388:            }
0389:
0390:            /**
0391:             * Get the lock depth  
0392:             * @return An int (WEBDAV.DEPTH_0 or WEBDAV.DEPTH_INFINITY)
0393:             */
0394:            protected int getCurrentLockDepth() {
0395:                return getInt(ATTR_LOCK_DEPTH, WEBDAV.DEPTH_INFINITY);
0396:            }
0397:
0398:            /**
0399:             * Get the username of the client that lock the resource
0400:             */
0401:            protected String getCurrentLockUsername(DAVRequest request) {
0402:                String username = (String) getValue(ATTR_LOCK_USERNAME, null);
0403:                if ((username == null) && (request != null)) {
0404:                    username = (String) request.getState(LOCK_USERNAME);
0405:                }
0406:                return username;
0407:            }
0408:
0409:            private boolean hasLock() {
0410:                return definesAttribute(ATTR_LOCK_TOKEN);
0411:            }
0412:
0413:            /**
0414:             * Check if this resource or one of their parent (with depth equals
0415:             * to infinity) has been locked
0416:             * @param request the incomming request (it null isLocked will returns 
0417:             * true if and only if the resource has been personally locked, not one
0418:             * of its parents)
0419:             * @return a boolean
0420:             */
0421:            protected boolean isLocked(DAVRequest request) {
0422:                if (hasLock()) {
0423:                    if (debug) {
0424:                        System.out.println(">>> Checking timeout...");
0425:                        System.out.println(System.currentTimeMillis() + " > ");
0426:                        System.out.println(getTokenExpirationDate(null));
0427:                    }
0428:                    if (System.currentTimeMillis() > getTokenExpirationDate(null)) {
0429:                        // timeout reached, remove the lock
0430:                        unlock();
0431:                        return false;
0432:                    }
0433:                    return true;
0434:                } else {
0435:                    return ((request != null) && (request.hasState(LOCK_TOKEN)));
0436:                }
0437:            }
0438:
0439:            protected void setTimeout(String timeouts[]) {
0440:                setValue(ATTR_LOCK_DATE, new Long(System.currentTimeMillis()));
0441:                setValue(ATTR_LOCK_TIMEOUT, DEFAULT_LOCK_TIMEOUT); // default
0442:                if (timeouts != null) {
0443:                    int len = timeouts.length;
0444:                    for (int i = 0; i < len; i++) {
0445:                        if (timeouts[i].startsWith("Second-")) {
0446:                            String sec = timeouts[i].substring(7);
0447:                            long timeout = Long.parseLong(sec) * 1000; // in ms
0448:                            if (timeout > MAX_LOCK_TIMEOUT.longValue()) {
0449:                                setValue(ATTR_LOCK_TIMEOUT, MAX_LOCK_TIMEOUT);
0450:                            } else if (timeout > 0) {
0451:                                setValue(ATTR_LOCK_TIMEOUT, new Long(timeout));
0452:                            } else {
0453:                                setValue(ATTR_LOCK_TIMEOUT,
0454:                                        DEFAULT_LOCK_TIMEOUT);
0455:                            }
0456:                            break;
0457:                        }
0458:                    }
0459:                }
0460:
0461:            }
0462:
0463:            protected synchronized void refreshLock(String timeouts[]) {
0464:                setTimeout(timeouts);
0465:            }
0466:
0467:            /**
0468:             * lock this resource
0469:             * @param token the lock token
0470:             * @param depth the lock depth (0 or -1)
0471:             * @param timeout the lock timeout
0472:             */
0473:            protected synchronized void lock(String token, int depth,
0474:                    String timeouts[], String username, Node owner)
0475:                    throws HTTPException {
0476:                setValue(ATTR_LOCK_TOKEN, token);
0477:                if (username != null) {
0478:                    setValue(ATTR_LOCK_USERNAME, username);
0479:                } else if (debug) {
0480:                    System.out.println("************************************");
0481:                    System.out.println("WARNING NULL USER");
0482:                    System.out.println("************************************");
0483:                }
0484:                setValue(ATTR_LOCK_DEPTH, new Integer(depth));
0485:                setLockOwner(owner);
0486:                setTimeout(timeouts);
0487:            }
0488:
0489:            protected void unlock() {
0490:                setValue(ATTR_LOCK_TOKEN, null);
0491:                setValue(ATTR_LOCK_DEPTH, null);
0492:                setValue(ATTR_LOCK_TIMEOUT, null);
0493:                setValue(ATTR_LOCK_DATE, null);
0494:                setValue(ATTR_LOCK_OWNER, null);
0495:                setValue(ATTR_LOCK_USERNAME, null);
0496:            }
0497:
0498:            protected void addSupportedLock(DAVProperties prop) {
0499:                // <supportedlock>
0500:                Element sl = prop.addDAVNode(DAVNode.SUPPORTEDLOCK_NODE, null);
0501:                // <lockentry>
0502:                Element le = DAVNode.addDAVNode(sl, DAVNode.LOCKENTRY_NODE,
0503:                        null);
0504:                // <lockscope><exclusive></lockscope>
0505:                Element ls = DAVNode.addDAVNode(le, DAVNode.LOCKSCOPE_NODE,
0506:                        null);
0507:                DAVNode.addDAVNode(ls, DAVNode.EXCLUSIVE_NODE, null);
0508:                // <locktype><write></locktype>
0509:                Element lt = DAVNode
0510:                        .addDAVNode(le, DAVNode.LOCKTYPE_NODE, null);
0511:                DAVNode.addDAVNode(lt, DAVNode.WRITE_NODE, null);
0512:            }
0513:
0514:            protected void addLockDiscovery(DAVRequest request,
0515:                    DAVProperties prop) {
0516:                addLockDiscovery(request, prop.getNode());
0517:            }
0518:
0519:            protected void addLockDiscovery(DAVRequest request, Node parent) {
0520:                if (isLocked(request)) {
0521:                    Element ld = DAVNode.addDAVNode(parent,
0522:                            DAVNode.LOCKDISCOVERY_NODE, null);
0523:                    Element al = DAVNode.addDAVNode(ld,
0524:                            DAVNode.ACTIVELOCK_NODE, null);
0525:                    // locktype
0526:                    Element lt = DAVNode.addDAVNode(al, DAVNode.LOCKTYPE_NODE,
0527:                            null);
0528:                    DAVNode.addDAVNode(lt, DAVNode.WRITE_NODE, null);
0529:                    // lockscope
0530:                    Element ls = DAVNode.addDAVNode(al, DAVNode.LOCKSCOPE_NODE,
0531:                            null);
0532:                    DAVNode.addDAVNode(ls, DAVNode.EXCLUSIVE_NODE, null);
0533:                    // depth
0534:                    String depth = request.depthToString(getCurrentLockDepth());
0535:                    DAVNode.addDAVNode(al, DAVNode.DEPTH_NODE, depth);
0536:                    // owner
0537:                    Node owner = getCurrentLockOwner(request);
0538:                    if (owner != null) {
0539:                        DAVNode.importNode(parent.getOwnerDocument(), al,
0540:                                owner, true);
0541:                    }
0542:                    // timeout
0543:                    String timeout = "Second-"
0544:                            + (getCurrentLockTimeout(request) / 1000);
0545:                    DAVNode.addDAVNode(al, DAVNode.TIMEOUT_NODE, timeout);
0546:                    // lock token
0547:                    Element ltk = DAVNode.addDAVNode(al,
0548:                            DAVNode.LOCKTOKEN_NODE, null);
0549:                    DAVNode.addDAVNode(ltk, DAVNode.HREF_NODE,
0550:                            getCurrentLockToken(request));
0551:                }
0552:            }
0553:
0554:            /**
0555:             * Get the dead properties
0556:             * @return a ArrayDictionary instance
0557:             * @see org.w3c.util.ArrayDictionary
0558:             */
0559:            public ArrayDictionary getDeadProperties() {
0560:                return (ArrayDictionary) getValue(ATTR_DEAD_PROPERTIES, null);
0561:            }
0562:
0563:            protected Hashtable deadindex = null; // <namespace, document>
0564:
0565:            protected boolean deadpropmodified = false;
0566:
0567:            protected synchronized Hashtable getDeadPropertiesIndex() {
0568:                if (deadindex == null) {
0569:                    ArrayDictionary dic = getDeadProperties();
0570:                    if (dic == null) {
0571:                        return new Hashtable();
0572:                    }
0573:                    Enumeration denum = dic.keys();
0574:                    deadindex = new Hashtable(dic.size());
0575:                    while (denum.hasMoreElements()) {
0576:                        String key = (String) denum.nextElement();
0577:                        Base64Decoder decoder = new Base64Decoder((String) dic
0578:                                .get(key));
0579:                        try {
0580:                            String decoded = decoder.processString();
0581:                            ByteArrayInputStream in = new ByteArrayInputStream(
0582:                                    decoded.getBytes());
0583:                            Document doc = DAVBody.getDocument(in, null);
0584:                            deadindex.put(key, doc);
0585:                        } catch (Base64FormatException ex) {
0586:                            ex.printStackTrace();
0587:                        } catch (IOException ex) {
0588:                            ex.printStackTrace();
0589:                        } catch (SAXException ex) {
0590:                            ex.printStackTrace();
0591:                        }
0592:                    }
0593:                }
0594:                return deadindex;
0595:            }
0596:
0597:            protected synchronized void setDeadProperty(Element el)
0598:                    throws DOMException {
0599:                if (deadindex == null) {
0600:                    deadindex = new Hashtable();
0601:                }
0602:                String ns = el.getNamespaceURI();
0603:                if (ns == null) {
0604:                    throw new DOMException(DOMException.NAMESPACE_ERR,
0605:                            "Missing namespace.");
0606:                }
0607:                Document doc = (Document) getDeadPropertiesIndex().get(ns);
0608:                if (doc == null) {
0609:                    doc = DAVBody.createDocumentNS(DAVNode.PROP_NODE, ns, el
0610:                            .getPrefix());
0611:                    Element prop = doc.getDocumentElement();
0612:                    Node imported = doc.importNode(el, true);
0613:                    prop.appendChild(imported);
0614:                    deadindex.put(ns, doc);
0615:                    deadpropmodified = true;
0616:                } else {
0617:                    Element prop = doc.getDocumentElement();
0618:                    DAVProperties dp = DAVFactory.createProperties(prop);
0619:                    Element props[] = dp.getProperties();
0620:                    int len = props.length;
0621:                    for (int i = 0; i < len; i++) {
0622:                        Element p = props[i];
0623:                        if (p.getNamespaceURI().equals(ns)
0624:                                && p.getLocalName().equals(el.getLocalName())) {
0625:                            // same, replace
0626:                            prop.replaceChild(doc.importNode(el, true), p);
0627:                            deadpropmodified = true;
0628:                            return;
0629:                        }
0630:                    }
0631:                    prop.appendChild(doc.importNode(el, true));
0632:                    deadpropmodified = true;
0633:                }
0634:            }
0635:
0636:            protected synchronized void removeDeadProperty(Element el)
0637:                    throws DOMException {
0638:                String name = el.getNodeName();
0639:                String ns = el.getNamespaceURI();
0640:                if (ns == null) {
0641:                    throw new DOMException(DOMException.NAMESPACE_ERR,
0642:                            "Missing namespace");
0643:                }
0644:                Document doc = (Document) getDeadPropertiesIndex().get(ns);
0645:                if (doc != null) {
0646:                    Element prop = doc.getDocumentElement();
0647:                    DAVProperties dp = DAVFactory.createProperties(prop);
0648:                    Element props[] = dp.getProperties();
0649:                    int len = props.length;
0650:                    for (int i = 0; i < len; i++) {
0651:                        Element p = props[i];
0652:                        if (p.getNamespaceURI().equals(ns)
0653:                                && p.getLocalName().equals(el.getLocalName())) {
0654:                            prop.removeChild(p);
0655:                            deadpropmodified = true;
0656:                            return;
0657:                        }
0658:                    }
0659:                }
0660:                String msg = el.getLocalName()
0661:                        + " property cannot be removed, not found";
0662:                throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
0663:            }
0664:
0665:            protected synchronized void reloadDeadProperties() {
0666:                // will be reloaded later...
0667:                deadindex = null;
0668:                deadpropmodified = false;
0669:            }
0670:
0671:            protected synchronized void saveDeadProperties() {
0672:                if (deadpropmodified) {
0673:                    ArrayDictionary dic = new ArrayDictionary(deadindex.size());
0674:                    Enumeration denum = deadindex.keys();
0675:                    while (denum.hasMoreElements()) {
0676:                        String ns = (String) denum.nextElement();
0677:                        Document doc = (Document) deadindex.get(ns);
0678:                        ByteArrayOutputStream out = new ByteArrayOutputStream();
0679:                        OutputFormat format = new OutputFormat(doc,
0680:                                WEBDAV.ENCODING, true);
0681:                        format.setOmitXMLDeclaration(false);
0682:                        format.setPreserveSpace(true);
0683:                        XMLSerializer serializer = new XMLSerializer(out,
0684:                                format);
0685:                        try {
0686:                            serializer.serialize(doc);
0687:                            if (debug)
0688:                                System.out.println("["
0689:                                        + out.toString(WEBDAV.ENCODING) + "]");
0690:                            Base64Encoder encoder = new Base64Encoder(out
0691:                                    .toString(WEBDAV.ENCODING));
0692:                            dic.put(ns, encoder.processString());
0693:                        } catch (IOException ex) {
0694:                            ex.printStackTrace();
0695:                        }
0696:                    }
0697:                    setValue(ATTR_DEAD_PROPERTIES, dic);
0698:                    deadpropmodified = false;
0699:                }
0700:            }
0701:
0702:            /**
0703:             * get the Allowed methods for this resource
0704:             * @return an HttpTokenList
0705:             */
0706:            protected HttpTokenList getAllow() {
0707:                allowed = super .getAllow();
0708:                allowed.addToken("PROPFIND", false);
0709:                allowed.addToken("PROPPATCH", false);
0710:                allowed.addToken("MKCOL", false);
0711:                allowed.addToken("COPY", false);
0712:                allowed.addToken("MOVE", false);
0713:                allowed.addToken("LOCK", false);
0714:                allowed.addToken("UNLOCK", false);
0715:                return allowed;
0716:            }
0717:
0718:            protected DAVBody getBody(DAVRequest request) throws HTTPException {
0719:                try {
0720:                    InputStream in = request.getInputStream();
0721:                    if ((in instanceof  ContentLengthInputStream)
0722:                            && (request.getContentLength() == 0)) {
0723:                        return null;
0724:                    }
0725:                    if (in != null) {
0726:                        return new DAVBody(in);
0727:                    }
0728:                    return null;
0729:                } catch (Exception ex) {
0730:                    Reply error = request.makeReply(HTTP.BAD_REQUEST);
0731:                    error.setContent("Invalid request: " + ex.getMessage());
0732:                    throw new HTTPException(error);
0733:                }
0734:            }
0735:
0736:            /**
0737:             * The WEBDAV OPTIONS method replies with the DAV Header
0738:             * @param request The request to handle.
0739:             * @exception ProtocolException In case of errors.
0740:             * @exception ResourceException If the resource got a fatal error.
0741:             */
0742:            public Reply options(Request request) throws ProtocolException,
0743:                    ResourceException {
0744:                DAVReply reply = (DAVReply) super .options((Request) request);
0745:                reply.setDAV(WEBDAV.CLASS_2_COMPLIANT);
0746:                return reply;
0747:            }
0748:
0749:            /**
0750:             * Perform the request
0751:             * @param req The request to handle.
0752:             * @exception ProtocolException If processsing the request failed.
0753:             * @exception ResourceException If the resource got a fatal error.
0754:             */
0755:
0756:            public ReplyInterface perform(RequestInterface req)
0757:                    throws ProtocolException, ResourceException {
0758:                if (req instanceof  DAVRequest) {
0759:                    DAVRequest request = (DAVRequest) req;
0760:                    int check = checkIf(request);
0761:                    if (check == COND_FAILED) {
0762:                        request.skipBody();
0763:                        Reply reply = request
0764:                                .makeReply(HTTP.PRECONDITION_FAILED);
0765:                        reply.setContent("Pre-conditions failed.");
0766:                        reply.setContentMD5(null);
0767:                        return reply;
0768:                    } else if (check == COND_OK || check == 0) {
0769:                        if (isLockable(request) && isLocked(request)) {
0770:                            request.skipBody();
0771:                            Reply reply = request.makeReply(WEBDAV.LOCKED);
0772:                            reply.setContent("The resource is locked");
0773:                            return reply;
0774:                        }
0775:                    } else if ((check == COND_OK_LOCK)
0776:                            && (!checkLockOwner(request))) {
0777:                        Reply reply = request.makeReply(WEBDAV.LOCKED);
0778:                        reply.setContent("The resource is locked");
0779:                        return reply;
0780:                    }
0781:                }
0782:                return super .perform(req);
0783:            }
0784:
0785:            /**
0786:             * The handler for unknown method replies with a not implemented.
0787:             * @param request The request to handle.
0788:             * @exception ProtocolException If processsing the request failed.
0789:             * @exception ResourceException If the resource got a fatal error.
0790:             */
0791:            public Reply extended(Request request) throws ProtocolException,
0792:                    ResourceException {
0793:                if (request instanceof  DAVRequest) {
0794:                    DAVRequest davrequest = (DAVRequest) request;
0795:                    String method = davrequest.getMethod();
0796:                    Reply reply = null;
0797:                    if (method.equals("PROPFIND")) {
0798:                        reply = propfind(davrequest);
0799:                    } else if (method.equals("PROPPATCH")) {
0800:                        reply = proppatch(davrequest);
0801:                    } else if (method.equals("MKCOL")) {
0802:                        reply = mkcol(davrequest);
0803:                    } else if (method.equals("COPY")) {
0804:                        reply = copy(davrequest);
0805:                    } else if (method.equals("MOVE")) {
0806:                        reply = move(davrequest);
0807:                    } else if (method.equals("LOCK")) {
0808:                        reply = lock(davrequest);
0809:                    } else if (method.equals("UNLOCK")) {
0810:                        reply = unlock(davrequest);
0811:                    } else {
0812:                        reply = davextended(davrequest);
0813:                    }
0814:                    return reply;
0815:                }
0816:                String method = request.getMethod();
0817:                Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED);
0818:                error.setContent("Method " + method + " not implemented.");
0819:                throw new HTTPException(error);
0820:            }
0821:
0822:            public Reply davextended(DAVRequest request)
0823:                    throws ProtocolException, ResourceException {
0824:                String method = request.getMethod();
0825:                Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED);
0826:                error.setContent("Method " + method + " not implemented.");
0827:                throw new HTTPException(error);
0828:            }
0829:
0830:            protected String decodeURL(DAVRequest request, String encoded)
0831:                    throws HTTPException {
0832:                try {
0833:                    return DAVParser.decodeURL(encoded);
0834:                } catch (HttpInvalidValueException ex) {
0835:                    Reply error = request.makeReply(HTTP.BAD_REQUEST);
0836:                    error.setContent("Invalid request: " + ex.getMessage());
0837:                    throw new HTTPException(error);
0838:                }
0839:            }
0840:
0841:            protected boolean isLockable(DAVRequest request) {
0842:                String method = request.getMethod();
0843:                return (method.equals("PUT") || method.equals("POST")
0844:                        || method.equals("PROPATCH") || method.equals("LOCK")
0845:                        || method.equals("MOVE") || method.equals("DELETE") || method
0846:                        .equals("MKCOL"));
0847:            }
0848:
0849:            protected boolean checkLockOwner(DAVRequest request) {
0850:                String user = (String) request
0851:                        .getState(AuthFilter.STATE_AUTHUSER);
0852:                if (debug) {
0853:                    System.out.println("REQ  USER : [" + user + "]");
0854:                    System.out.println("LOCK USER : ["
0855:                            + getCurrentLockUsername(request) + "]");
0856:                }
0857:                String lockuser = getCurrentLockUsername(request);
0858:                if (lockuser == null) {
0859:                    return true;
0860:                }
0861:                if (user != null) {
0862:                    return user.equals(lockuser);
0863:                } else {
0864:                    return false;
0865:                }
0866:            }
0867:
0868:            /**
0869:             * Check the <code>If</code> condition of that request.
0870:             * @param request The request to check.
0871:             * @return An integer, either <code>COND_FAILED</cond> if condition
0872:             * was checked, but failed, <code>COND_OK</code> if condition was checked
0873:             * and succeeded, or <strong>0</strong> if the condition was not checked
0874:             * at all (eg because the resource or the request didn't support it).
0875:             */
0876:            protected int checkIf(DAVRequest request) throws HTTPException {
0877:                URL url = getURL(request);
0878:                String surl = url.toExternalForm();
0879:                DAVIf ifs[] = request.getIf();
0880:                if (ifs != null) {
0881:                    if (debug) {
0882:                        System.out.println(">>> Check If Header...");
0883:                    }
0884:                    int len = ifs.length;
0885:                    boolean tagged = request.isTaggedListIfHeader();
0886:                    boolean lockchecked = false;
0887:
0888:                    for (int i = 0; i < len; i++) {
0889:                        DAVIf dif = ifs[i];
0890:                        boolean parent = false;
0891:                        // check that if
0892:                        if (dif.hasResource()) {
0893:                            URL resURL = null;
0894:                            try {
0895:                                resURL = new URL(url, dif.getResource());
0896:                            } catch (MalformedURLException ex) {
0897:                                ex.printStackTrace();
0898:                                continue;
0899:                            }
0900:                            if (!resURL.equals(url)) {
0901:                                if (surl.startsWith(resURL.toExternalForm())) {
0902:                                    // parent lock
0903:                                    parent = true;
0904:                                } else {
0905:                                    // not us
0906:                                    continue;
0907:                                }
0908:                            }
0909:                        }
0910:                        ListIterator it = dif.getTokenListIterator();
0911:                        while (it.hasNext()) { // OR
0912:                            boolean checked = true;
0913:                            boolean not = false;
0914:                            LinkedList list = (LinkedList) it.next();
0915:                            ListIterator it2 = list.listIterator(0);
0916:                            while (it2.hasNext()) { // AND
0917:                                Object tok = it2.next();
0918:                                if (tok instanceof  DAVStateToken) {
0919:                                    DAVStateToken dst = (DAVStateToken) tok;
0920:                                    if (matchLockToken(request, dst
0921:                                            .getStateToken())) {
0922:                                        if (dst.isNot()) {
0923:                                            checked = false;
0924:                                            not = false;
0925:                                        } else {
0926:                                            if (debug)
0927:                                                System.out
0928:                                                        .println(">>> Lock checked");
0929:                                            lockchecked = true;
0930:                                        }
0931:                                    } else if (!dst.isNot()) {
0932:                                        checked = false;
0933:                                    }
0934:                                } else if ((!parent)
0935:                                        && (tok instanceof  DAVEntityTag)) {
0936:                                    DAVEntityTag det = (DAVEntityTag) tok;
0937:                                    if (matchETag(det)) {
0938:                                        if (debug)
0939:                                            System.out
0940:                                                    .println(">>> ETag checked");
0941:                                        if (det.isNot()) {
0942:                                            checked = false;
0943:                                            not = false;
0944:                                        }
0945:                                    } else if (!det.isNot()) {
0946:                                        checked = false;
0947:                                    }
0948:                                }
0949:                            }
0950:                            if (!parent) {
0951:                                if (checked && lockchecked) {
0952:                                    return COND_OK_LOCK;
0953:                                } else if (checked) {
0954:                                    return COND_OK;
0955:                                }
0956:                            }
0957:                        }
0958:                    }
0959:                    if (tagged) {
0960:                        if (lockchecked) {
0961:                            return COND_OK_LOCK;
0962:                        } else {
0963:                            return 0;
0964:                        }
0965:                    } else {
0966:                        return COND_FAILED;
0967:                    }
0968:                }
0969:                return 0;
0970:            }
0971:
0972:            protected boolean matchETag(HttpEntityTag retag) {
0973:                HttpEntityTag etag = getETag();
0974:                if (etag != null) {
0975:                    return etag.getTag().equals(retag.getTag());
0976:                }
0977:                return false;
0978:            }
0979:
0980:            protected boolean matchLockToken(DAVRequest request,
0981:                    String locktoken) {
0982:                return locktoken.equals(getCurrentLockToken(request));
0983:            }
0984:
0985:            /**
0986:             * The WEBDAV DELETE method, actually the resource (file, directory)
0987:             * is moved into the trash directory which is not accessible via HTTP.
0988:             * @param request The request to handle.
0989:             * @exception ProtocolException If processsing the request failed.
0990:             * @exception ResourceException If the resource got a fatal error.
0991:             */
0992:
0993:            public Reply delete(Request request) throws ProtocolException,
0994:                    ResourceException {
0995:                return super .delete(request);
0996:            }
0997:
0998:            /**
0999:             * Get this resource body.
1000:             * If we are allowed to convert GET requests to POST, than we first
1001:             * check to see if there is some search string in the request, and continue
1002:             * with normal POST request processing.
1003:             * <p>If there is no search string, or if we are not allowed to convert
1004:             * GETs to POSTs, than we just invoke our <code>super</code> method,
1005:             * which will perform the appropriate job.
1006:             * @param request The request to handle.
1007:             * @exception ProtocolException If request couldn't be processed.
1008:             * @exception ResourceException If the resource got a fatal error.
1009:             */
1010:            public Reply get(Request request) throws ProtocolException,
1011:                    ResourceException {
1012:                return super .get(request);
1013:            }
1014:
1015:            /**
1016:             * The WEBDAV PUT method.
1017:             * @param request The request to handle.
1018:             * @exception ProtocolException If processsing the request failed.
1019:             * @exception ResourceException If the resource got a fatal error.
1020:             */
1021:
1022:            public Reply put(Request request) throws ProtocolException,
1023:                    ResourceException {
1024:                return super .put(request);
1025:            }
1026:
1027:            /**
1028:             * Perform the post method.
1029:             * @param request The request to handle.
1030:             * @exception ProtocolException If request couldn't be processed.
1031:             * @exception ResourceException If the resource got a fatal error.
1032:             */
1033:            public Reply post(Request request) throws ProtocolException,
1034:                    ResourceException {
1035:                return super .post(request);
1036:            }
1037:
1038:            private HTTPException notYetImplemented(DAVRequest request)
1039:                    throws ProtocolException {
1040:                Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED);
1041:                error.setContent("Method " + request.getMethod()
1042:                        + " not implemented.");
1043:                throw new HTTPException(error);
1044:            }
1045:
1046:            protected boolean hasProperty(int idx) {
1047:                return (getValue(idx, null) != null);
1048:            }
1049:
1050:            protected boolean hasStringProperty(int idx) {
1051:                String value = (String) getValue(idx, "");
1052:                return (value.length() > 0);
1053:            }
1054:
1055:            protected boolean hasLongProperty(int idx) {
1056:                return (getLong(idx, -1) != -1);
1057:            }
1058:
1059:            protected boolean hasIntProperty(int idx) {
1060:                return (getInt(idx, -1) != -1);
1061:            }
1062:
1063:            protected void addCreationDate(DAVProperties props) {
1064:                Date d = new Date(getCreationDate());
1065:                String isodate = DateParser.getIsoDateNoMillis(d);
1066:                props.addProperty(DAVNode.CREATIONDATE_NODE, isodate);
1067:            }
1068:
1069:            protected void addDisplayName(DAVProperties props) {
1070:                String title = getTitle();
1071:                if ((title != null) && (title.length() > 0)) {
1072:                    props.addProperty(DAVNode.DISPLAYNAME_NODE, title);
1073:                }
1074:            }
1075:
1076:            protected void addContentLanguage(DAVProperties props) {
1077:                String lang = getContentLanguage();
1078:                if (lang != null) {
1079:                    props.addProperty(DAVNode.GETCONTENTLANGUAGE_NODE, lang);
1080:                }
1081:            }
1082:
1083:            protected void addContentType(DAVProperties props) {
1084:                MimeType mime = getContentType();
1085:                if (mime != null) {
1086:                    props.addProperty(DAVNode.GETCONTENTTYPE_NODE, mime
1087:                            .toString());
1088:                }
1089:            }
1090:
1091:            private void addCollectionContentType(DAVProperties props) {
1092:                props.addProperty(DAVNode.GETCONTENTTYPE_NODE,
1093:                        collectioncontenttype.toString());
1094:            }
1095:
1096:            protected void addContentLength(DAVProperties props) {
1097:                int length = getContentLength();
1098:                if (length >= 0) {
1099:                    props.addProperty(DAVNode.GETCONTENTLENGTH_NODE, String
1100:                            .valueOf(length));
1101:                }
1102:            }
1103:
1104:            protected void addETag(DAVProperties props) {
1105:                HttpEntityTag tag = getETag();
1106:                if (tag != null) {
1107:                    props.addProperty(DAVNode.GETETAG_NODE, tag.getTag());
1108:                }
1109:            }
1110:
1111:            protected void addLastModified(DAVProperties props) {
1112:                HttpDate hdate = HttpFactory.makeDate(getLastModified());
1113:                String httpdate = hdate.toString();
1114:                props.addProperty(DAVNode.GETLASTMODIFIED_NODE, httpdate);
1115:            }
1116:
1117:            protected void addResourceType(DAVProperties props) {
1118:                if (isCollection()) {
1119:                    props.setResourceType(DAVNode.COLLECTION_NODE);
1120:                } else {
1121:                    props.setResourceType(null);
1122:                }
1123:            }
1124:
1125:            protected void addIsCollection(DAVProperties props) {
1126:                props.addProperty(DAVNode.ISCOLLECTION_NODE,
1127:                        isCollection() ? "1" : "0");
1128:            }
1129:
1130:            /**
1131:             * Get the properties of our associated resource require in
1132:             * the given DAVProperties Object.
1133:             * @param doc the response XML Document
1134:             * @param dp the DAVProperties node in found the request body
1135:             * @return a DAVProperties instance 
1136:             */
1137:            protected DAVProperties getProperties(DAVRequest request,
1138:                    Document doc, DAVProperties dp) {
1139:                DAVProperties props = DAVFactory.createProperties(doc);
1140:                Element[] els = dp.getProperties();
1141:                int len = els.length;
1142:                for (int i = 0; i < len; i++) {
1143:                    Element el = els[i];
1144:                    String ns = el.getNamespaceURI();
1145:                    String propname = el.getLocalName();
1146:                    if ((ns == null) || (ns.equals(WEBDAV.NAMESPACE_URI))) {
1147:                        // live property
1148:                        if (propname.equals(DAVNode.CREATIONDATE_NODE)) {
1149:                            addCreationDate(props);
1150:                        } else if (propname.equals(DAVNode.DISPLAYNAME_NODE)) {
1151:                            addDisplayName(props);
1152:                        } else if (propname
1153:                                .equals(DAVNode.GETCONTENTLANGUAGE_NODE)) {
1154:                            addContentLanguage(props);
1155:                        } else if (propname.equals(DAVNode.GETCONTENTTYPE_NODE)) {
1156:                            addContentType(props);
1157:                        } else if (propname
1158:                                .equals(DAVNode.GETCONTENTLENGTH_NODE)) {
1159:                            addContentLength(props);
1160:                        } else if (propname.equals(DAVNode.GETETAG_NODE)) {
1161:                            addETag(props);
1162:                        } else if (propname
1163:                                .equals(DAVNode.GETLASTMODIFIED_NODE)) {
1164:                            addLastModified(props);
1165:                        } else if (propname.equals(DAVNode.LOCKDISCOVERY_NODE)) {
1166:                            addLockDiscovery(request, props);
1167:                        } else if (propname.equals(DAVNode.RESOURCETYPE_NODE)) {
1168:                            addResourceType(props);
1169:                        } else if (propname.equals(DAVNode.SOURCE_NODE)) {
1170:                            // FIXME
1171:                        } else if (propname.equals(DAVNode.SUPPORTEDLOCK_NODE)) {
1172:                            addSupportedLock(props);
1173:                        } else { // property not found
1174:                            // FIXME add with 404 reply
1175:                        }
1176:                    } else {
1177:                        // dead property
1178:                        Document pdoc = (Document) getDeadPropertiesIndex()
1179:                                .get(ns);
1180:                        if (pdoc != null) {
1181:                            Element prop = pdoc.getDocumentElement();
1182:                            DAVProperties dpns = DAVFactory
1183:                                    .createProperties(prop);
1184:                            Node pnode = dpns.getNodeNS(propname, ns);
1185:                            if (pnode != null) {
1186:                                props.addNodeNS(doc.importNode(pnode, true));
1187:                            }
1188:                        }
1189:                    }
1190:                }
1191:                return props;
1192:            }
1193:
1194:            protected DAVPropStat[] getPropStat(DAVRequest request,
1195:                    Document doc, DAVProperties dp) {
1196:                DAVProperties props = DAVFactory.createProperties(doc);
1197:                DAVProperties nfprops = null;
1198:                Element[] els = dp.getProperties();
1199:                int len = els.length;
1200:                for (int i = 0; i < len; i++) {
1201:                    Element el = els[i];
1202:                    String ns = el.getNamespaceURI();
1203:                    String propname = el.getLocalName();
1204:                    if ((ns == null) || (ns.equals(WEBDAV.NAMESPACE_URI))) {
1205:                        // live property
1206:                        if (propname.equals(DAVNode.CREATIONDATE_NODE)) {
1207:                            addCreationDate(props);
1208:                        } else if (propname.equals(DAVNode.DISPLAYNAME_NODE)) {
1209:                            addDisplayName(props);
1210:                        } else if (propname
1211:                                .equals(DAVNode.GETCONTENTLANGUAGE_NODE)) {
1212:                            addContentLanguage(props);
1213:                        } else if (propname.equals(DAVNode.GETCONTENTTYPE_NODE)) {
1214:                            addContentType(props);
1215:                        } else if (propname
1216:                                .equals(DAVNode.GETCONTENTLENGTH_NODE)) {
1217:                            addContentLength(props);
1218:                        } else if (propname.equals(DAVNode.GETETAG_NODE)) {
1219:                            addETag(props);
1220:                        } else if (propname
1221:                                .equals(DAVNode.GETLASTMODIFIED_NODE)) {
1222:                            addLastModified(props);
1223:                        } else if (propname.equals(DAVNode.LOCKDISCOVERY_NODE)) {
1224:                            addLockDiscovery(request, props);
1225:                        } else if (propname.equals(DAVNode.RESOURCETYPE_NODE)) {
1226:                            addResourceType(props);
1227:                        } else if (propname.equals(DAVNode.SOURCE_NODE)) {
1228:                            // FIXME
1229:                        } else if (propname.equals(DAVNode.SUPPORTEDLOCK_NODE)) {
1230:                            addSupportedLock(props);
1231:                        } else { // property not found
1232:                            if (nfprops == null) {
1233:                                nfprops = DAVFactory.createProperties(doc);
1234:                            }
1235:                            Element e;
1236:                            e = doc.createElementNS(
1237:                                    "http://www.w3.org/Jigsaw/Webdav/",
1238:                                    propname);
1239:                            e.setPrefix("F");
1240:                            nfprops.addNodeNS(nfprops.getNode(), (Node) e);
1241:                        }
1242:                    } else {
1243:                        // dead property
1244:                        Document pdoc = (Document) getDeadPropertiesIndex()
1245:                                .get(ns);
1246:                        if (pdoc != null) {
1247:                            Element prop = pdoc.getDocumentElement();
1248:                            DAVProperties dpns = DAVFactory
1249:                                    .createProperties(prop);
1250:                            Node pnode = dpns.getNodeNS(propname, ns);
1251:                            if (pnode != null) {
1252:                                props.addNodeNS(doc.importNode(pnode, true));
1253:                            }
1254:                        }
1255:                    }
1256:                }
1257:                DAVPropStat[] dps = null;
1258:                if (nfprops != null) {
1259:                    dps = new DAVPropStat[2];
1260:                    dps[1] = DAVFactory.createPropStat(
1261:                            getStatusLine(HTTP.NOT_FOUND), doc);
1262:                    dps[1].addDAVNode(nfprops);
1263:                } else {
1264:                    dps = new DAVPropStat[1];
1265:                }
1266:                dps[0] = DAVFactory.createPropStat(getStatusLine(HTTP.OK), doc);
1267:                dps[0].addDAVNode(props);
1268:                return dps;
1269:            }
1270:
1271:            /**
1272:             * Get all the properties of our associated resource.
1273:             * @param doc the response XML Document
1274:             * @return a DAVProperties instance 
1275:             */
1276:            protected DAVProperties getProperties(DAVRequest request,
1277:                    Document doc) {
1278:                DAVProperties props = DAVFactory.createProperties(doc);
1279:                // creationdate
1280:                addCreationDate(props);
1281:                // displayname
1282:                addDisplayName(props);
1283:                // getcontentlanguage
1284:                addContentLanguage(props);
1285:                // getcontentlength
1286:                addContentLength(props);
1287:                // getetag
1288:                addETag(props);
1289:                // getlastmodified
1290:                addLastModified(props);
1291:                // getcontenttype
1292:                if (isCollection()) {
1293:                    addCollectionContentType(props);
1294:                } else {
1295:                    addContentType(props);
1296:                }
1297:                // lockdiscovery
1298:                addLockDiscovery(request, props);
1299:                // resourcetype
1300:                addResourceType(props);
1301:                // supportedlock
1302:                addSupportedLock(props);
1303:                // non std stuff
1304:                addIsCollection(props);
1305:                // Dead properties
1306:                Hashtable dp = getDeadPropertiesIndex();
1307:                Enumeration e = dp.keys();
1308:                while (e.hasMoreElements()) {
1309:                    String ns = (String) e.nextElement();
1310:                    Document d = (Document) dp.get(ns);
1311:                    Element el = d.getDocumentElement(); // prop
1312:                    try {
1313:                        DAVNode.exportChildren(doc, props.getNode(), el, true);
1314:                    } catch (DOMException ex) {
1315:                        ex.printStackTrace();
1316:                    }
1317:                }
1318:                return props;
1319:            }
1320:
1321:            protected DAVProperties getPropertiesForCopy(Document doc) {
1322:                DAVProperties props = DAVFactory.createProperties(doc);
1323:                // displayname
1324:                addDisplayName(props);
1325:                // getcontentlanguage
1326:                addContentLanguage(props);
1327:                // getcontenttype
1328:                addContentType(props);
1329:                // source
1330:
1331:                // Dead properties
1332:                Hashtable dp = getDeadPropertiesIndex();
1333:                Enumeration e = dp.keys();
1334:                while (e.hasMoreElements()) {
1335:                    String ns = (String) e.nextElement();
1336:                    Document d = (Document) dp.get(ns);
1337:                    Element el = d.getDocumentElement(); // prop
1338:                    try {
1339:                        DAVNode.exportChildren(doc, props.getNode(), el, true);
1340:                    } catch (DOMException ex) {
1341:                        ex.printStackTrace();
1342:                    }
1343:                }
1344:                return props;
1345:            }
1346:
1347:            /**
1348:             * Get all the property names of our associated resource.
1349:             * @param doc the response XML Document
1350:             * @return a DAVProperties instance 
1351:             */
1352:            protected DAVProperties getPropNames(DAVRequest request,
1353:                    Document doc) {
1354:                DAVProperties props = DAVFactory.createProperties(doc);
1355:                // dead property
1356:                Hashtable dp = getDeadPropertiesIndex();
1357:                Enumeration e = dp.keys();
1358:                while (e.hasMoreElements()) {
1359:                    String ns = (String) e.nextElement();
1360:                    Document d = (Document) dp.get(ns);
1361:                    Element el = d.getDocumentElement(); // prop
1362:                    try {
1363:                        DAVNode.exportChildren(doc, props.getNode(), el, false);
1364:                    } catch (DOMException ex) {
1365:                        ex.printStackTrace();
1366:                    }
1367:                }
1368:                // live properties
1369:                if (hasStringProperty(ATTR_TITLE)) {
1370:                    props.addProperty(DAVNode.DISPLAYNAME_NODE);
1371:                }
1372:                if (hasStringProperty(ATTR_CONTENT_LANGUAGE)) {
1373:                    props.addProperty(DAVNode.GETCONTENTLANGUAGE_NODE);
1374:                }
1375:                if (getETag() != null) {
1376:                    props.addProperty(DAVNode.GETETAG_NODE);
1377:                }
1378:                if (hasProperty(ATTR_CONTENT_TYPE)) {
1379:                    props.addProperty(DAVNode.GETCONTENTTYPE_NODE);
1380:                }
1381:                if (hasIntProperty(ATTR_CONTENT_LENGTH)) {
1382:                    props.addProperty(DAVNode.GETCONTENTLENGTH_NODE);
1383:                }
1384:                if (hasLongProperty(ATTR_CREATION_DATE)) {
1385:                    props.addProperty(DAVNode.CREATIONDATE_NODE);
1386:                }
1387:                if (getCurrentLockToken(request) != null) {
1388:                    props.addProperty(DAVNode.LOCKDISCOVERY_NODE);
1389:                }
1390:                props.addProperty(DAVNode.GETLASTMODIFIED_NODE);
1391:                props.addProperty(DAVNode.RESOURCETYPE_NODE);
1392:                props.addProperty(DAVNode.SUPPORTEDLOCK_NODE);
1393:                return props;
1394:            }
1395:
1396:            /**
1397:             * Get an appropriate DAV Response to the given PROPFIND request
1398:             * @param request the DAV Request
1399:             * @param dpf the DAVPropFind XML Node (can be null)
1400:             * @param document the XML document
1401:             * @return a DAVResponse
1402:             */
1403:            protected DAVResponse getResponse(DAVRequest request,
1404:                    DAVPropFind dpf, Document document) {
1405:                if (fresource != null) {
1406:                    fresource.checkContent();
1407:                }
1408:                updateCachedHeaders();
1409:
1410:                DAVProperties props = null;
1411:                if (dpf != null) {
1412:                    if (dpf.findPropNames()) {
1413:                        props = getPropNames(request, document);
1414:                    } else if (dpf.findAllProps()) {
1415:                        props = getProperties(request, document);
1416:                    } else {
1417:                        DAVProperties dp = dpf.getProperties();
1418:                        //		props = getProperties(request, document, dp);
1419:                        DAVPropStat[] dps = getPropStat(request, document, dp);
1420:                        DAVResponse dr = DAVFactory.createResponse(
1421:                        //		    getURL(request).toExternalForm(),
1422:                                getURL(request).getFile(), document);
1423:                        for (int i = 0; i < dps.length; i++) {
1424:                            dr.addDAVNode(dps[i]);
1425:                        }
1426:                        return dr;
1427:                    }
1428:                } else { // default is all property values
1429:                    props = getProperties(request, document);
1430:                }
1431:                return DAVFactory.createPropStatResponse(
1432:                        //					 getURL(request).toExternalForm(),
1433:                        getURL(request).getFile(), getStatusLine(HTTP.OK),
1434:                        props, document);
1435:            }
1436:
1437:            /**
1438:             * Get an appropriate DAV Response to the given PROPFIND request from
1439:             * our children
1440:             * @param request the DAV Request
1441:             * @param dpf the DAVPropFind XML Node (can be null)
1442:             * @param document the XML document
1443:             * @param deep do it recursivly if true
1444:             * @return a DAVResponse array
1445:             */
1446:            protected DAVResponse[] getChildResponses(DAVRequest request,
1447:                    DAVPropFind dpf, Document document, boolean deep) {
1448:                if (resource instanceof  ContainerResource) {
1449:                    Vector v = new Vector();
1450:                    ContainerResource cresource = (ContainerResource) resource;
1451:                    Enumeration e = cresource.enumerateResourceIdentifiers();
1452:                    ResourceReference rr = null;
1453:                    FramedResource fr = null;
1454:                    while (e.hasMoreElements()) {
1455:                        String name = (String) e.nextElement();
1456:                        rr = cresource.lookup(name);
1457:                        if (rr != null) {
1458:                            try {
1459:                                fr = (FramedResource) rr.lock();
1460:                                if (fr == resource) { // for root
1461:                                    continue;
1462:                                }
1463:                                DAVFrame df = (DAVFrame) fr
1464:                                        .getFrame(DAVFrame.class);
1465:                                if (df != null) {
1466:                                    v.addElement(df.getResponse(request, dpf,
1467:                                            document));
1468:                                    if (deep
1469:                                            && (fr instanceof  ContainerResource)) {
1470:                                        DAVResponse responses[] = df
1471:                                                .getChildResponses(request,
1472:                                                        dpf, document, deep);
1473:                                        if (responses != null) {
1474:                                            int len = responses.length;
1475:                                            for (int i = 0; i < len; i++) {
1476:                                                v.addElement(responses[i]);
1477:                                            }
1478:                                        }
1479:                                    }
1480:                                } else {
1481:                                    // what should I do there?
1482:                                }
1483:                            } catch (InvalidResourceException ex) {
1484:                                // build error response?
1485:                            } finally {
1486:                                rr.unlock();
1487:                            }
1488:                        }
1489:                    }
1490:                    DAVResponse responses[] = new DAVResponse[v.size()];
1491:                    v.copyInto(responses);
1492:                    return responses;
1493:                }
1494:                return null;
1495:            }
1496:
1497:            /**
1498:             * Create a DAV reply for a specific DAV request.
1499:             * @param request the DAVRequest
1500:             * @param status the status of the reply
1501:             * @param document the XML content of the reply
1502:             * @return a Reply instance
1503:             */
1504:            protected Reply createDAVReply(DAVRequest request, int status,
1505:                    Document document) {
1506:                Reply reply = request.makeReply(status);
1507:                reply.setHeaderValue(Reply.H_CONTENT_TYPE, xmlcontenttype);
1508:                reply.setDate((System.currentTimeMillis() / 1000L) * 1000L);
1509:
1510:                ByteArrayOutputStream out = new ByteArrayOutputStream();
1511:
1512:                OutputFormat format = new OutputFormat(document,
1513:                        WEBDAV.ENCODING, true);
1514:                format.setOmitXMLDeclaration(false);
1515:                format.setPreserveSpace(false);
1516:                XMLSerializer serializer = new XMLSerializer(out, format);
1517:                try {
1518:                    serializer.serialize(document);
1519:                } catch (IOException ex) {
1520:                    ex.printStackTrace();
1521:                }
1522:
1523:                if (debugxml) {
1524:                    serializer = new XMLSerializer(System.out, format);
1525:                    try {
1526:                        serializer.serialize(document);
1527:                    } catch (IOException ex) {
1528:                        ex.printStackTrace();
1529:                    }
1530:                }
1531:
1532:                int len = out.size();
1533:                reply.setContentLength(len);
1534:
1535:                ByteArrayInputStream in = new ByteArrayInputStream(out
1536:                        .toByteArray());
1537:                reply.setStream(in);
1538:                return reply;
1539:            }
1540:
1541:            protected String getStatusLine(int status) {
1542:                return "HTTP/1.1 " + status + " "
1543:                        + DAVReply.getDAVReason(status);
1544:            }
1545:
1546:            /**
1547:             * Handle the PROPFIND request.
1548:             * @param request the WEBDAV request
1549:             * @return a Reply instance
1550:             * @exception ProtocolException If processsing the request failed.
1551:             * @exception ResourceException If the resource got a fatal error.
1552:             */
1553:            public Reply propfind(DAVRequest request) throws ProtocolException,
1554:                    ResourceException {
1555:                int depth = request.getDepth();
1556:                DAVBody body = getBody(request);
1557:                Document document = DAVBody
1558:                        .createDocument(DAVNode.MULTISTATUS_NODE);
1559:                DAVMultiStatus dms = DAVFactory.createMultiStatus(document
1560:                        .getDocumentElement());
1561:                DAVPropFind propfind = null;
1562:                DAVResponse dr = null;
1563:                if (body != null) {
1564:                    propfind = body.getPropFind();
1565:                }
1566:                switch (depth) {
1567:                case 0:
1568:                    dr = getResponse(request, propfind, document);
1569:                    dms.addDAVNode(dr);
1570:                    break;
1571:                case 1:
1572:                    dr = getResponse(request, propfind, document);
1573:                    dms.addDAVNode(dr);
1574:                    dms.addDAVNodes(getChildResponses(request, propfind,
1575:                            document, false));
1576:                    break;
1577:                default: // infinity
1578:                    dr = getResponse(request, propfind, document);
1579:                    dms.addDAVNode(dr);
1580:                    dms.addDAVNodes(getChildResponses(request, propfind,
1581:                            document, true));
1582:
1583:                }
1584:                return createDAVReply(request, WEBDAV.MULTI_STATUS, document);
1585:            }
1586:
1587:            protected DAVPropStat setDAVProperties(DAVProperties props,
1588:                    Document document) throws DAVPropertyException {
1589:                Element properties[] = props.getProperties();
1590:                int len = properties.length;
1591:                DAVProperties okdp = DAVFactory.createProperties(document);
1592:                try {
1593:                    for (int i = 0; i < len; i++) {
1594:                        Element el = properties[i];
1595:                        String ns = el.getNamespaceURI();
1596:                        if ((ns == null) || (ns.equals(WEBDAV.NAMESPACE_URI))) {
1597:                            // live property
1598:                            setLiveProperty(DAVFactory.createDAVNode(el), okdp,
1599:                                    document);
1600:                        } else {
1601:                            // dead property
1602:                            setDeadProperty(DAVFactory.createDAVNode(el), okdp,
1603:                                    document);
1604:                        }
1605:                    }
1606:                } catch (DAVPropertyException ex) {
1607:                    // something failed
1608:                    DAVPropStat dps = (DAVPropStat) ex.getReason();
1609:                    String msg = ex.getMessage();
1610:                    DAVPropStat stats[] = null;
1611:                    if (okdp.getNode().hasChildNodes()) {
1612:                        DAVPropStat okdps = DAVFactory.createPropStat(
1613:                                getStatusLine(HTTP.OK), okdp, document);
1614:                        stats = new DAVPropStat[2];
1615:                        stats[0] = okdps;
1616:                        stats[1] = dps;
1617:                    } else {
1618:                        stats = new DAVPropStat[1];
1619:                        stats[0] = dps;
1620:                    }
1621:                    // send ok properties and the one that failed
1622:                    throw new DAVPropertyException(msg, stats);
1623:                }
1624:                // everything is ok
1625:                if (okdp.getNode().hasChildNodes()) {
1626:                    return DAVFactory.createPropStat(getStatusLine(HTTP.OK),
1627:                            okdp, document);
1628:                }
1629:                return null;
1630:            }
1631:
1632:            protected void setDeadProperty(DAVNode node, DAVProperties okdp,
1633:                    Document document) throws DAVPropertyException {
1634:                Node n = node.getNode();
1635:                String name = n.getLocalName();
1636:                try {
1637:                    if (n.getNodeType() == n.ELEMENT_NODE) {
1638:                        Element el = (Element) n;
1639:                        setDeadProperty(el);
1640:                        okdp.addNodeNS(document.importNode(el, false));
1641:                    } else {
1642:                        DAVPropStat dps = DAVFactory.createPropStatNS(
1643:                                getStatusLine(HTTP.CONFLICT), document
1644:                                        .importNode(n, false), document);
1645:                        String msg = "Invalid XML : " + name;
1646:                        throw new DAVPropertyException(msg, dps);
1647:                    }
1648:                } catch (DOMException ex) {
1649:                    DAVPropStat dps = DAVFactory.createPropStatNS(
1650:                            getStatusLine(HTTP.CONFLICT), document.importNode(
1651:                                    n, false), document);
1652:                    throw new DAVPropertyException(ex.getMessage(), dps);
1653:                }
1654:            }
1655:
1656:            protected void setLiveProperty(DAVNode node, DAVProperties okdp,
1657:                    Document document) throws DAVPropertyException {
1658:                String name = node.getNode().getLocalName();
1659:                String value = node.getTextValue();
1660:                if (name.equals(DAVNode.DISPLAYNAME_NODE)) {
1661:                    setValue(ATTR_TITLE, value);
1662:                    okdp.addProperty(name);
1663:                } else if (name.equals(DAVNode.GETCONTENTLANGUAGE_NODE)) {
1664:                    setValue(ATTR_CONTENT_LANGUAGE, value);
1665:                    okdp.addProperty(name);
1666:                } else if (name.equals(DAVNode.SOURCE_NODE)) {
1667:                    // FIXME
1668:                } else if (name.equals(DAVNode.RESOURCETYPE_NODE)) {
1669:                    // FIXME
1670:                } else if (name.equals(DAVNode.GETCONTENTTYPE_NODE)) {
1671:                    try {
1672:                        MimeType mime = new MimeType(value);
1673:                        setValue(ATTR_CONTENT_TYPE, mime);
1674:                        okdp.addProperty(name);
1675:                    } catch (MimeTypeFormatException ex) {
1676:                        DAVPropStat dps = DAVFactory.createPropStat(
1677:                                getStatusLine(HTTP.CONFLICT), name, document);
1678:                        // throw exception now
1679:                        String msg = "Invalid value for " + name + " : "
1680:                                + value;
1681:                        throw new DAVPropertyException(msg, dps);
1682:                    }
1683:                } else if (isReadOnly(name)) {
1684:                    // forbidden
1685:                    DAVPropStat dps = DAVFactory.createPropStat(
1686:                            getStatusLine(HTTP.FORBIDDEN), name, document);
1687:                    throw new DAVPropertyException(
1688:                            name + " cannot be modified", dps);
1689:                } else {
1690:                    // not found so add it as a dead one
1691:                    setDeadProperty(node, okdp, document);
1692:                }
1693:            }
1694:
1695:            protected DAVPropStat removeDAVProperties(DAVProperties props,
1696:                    Document document) throws DAVPropertyException {
1697:                Element properties[] = props.getProperties();
1698:                int len = properties.length;
1699:                DAVProperties okdp = DAVFactory.createProperties(document);
1700:                try {
1701:                    for (int i = 0; i < len; i++) {
1702:                        Element el = properties[i];
1703:                        String ns = el.getNamespaceURI();
1704:                        if ((ns == null) || (ns.equals(WEBDAV.NAMESPACE_URI))) {
1705:                            // live property
1706:                            removeLiveProperty(DAVFactory.createDAVNode(el),
1707:                                    okdp, document);
1708:                        } else {
1709:                            // dead property
1710:                            removeDeadProperty(DAVFactory.createDAVNode(el),
1711:                                    okdp, document);
1712:                        }
1713:                    }
1714:                } catch (DAVPropertyException ex) {
1715:                    // something failed
1716:                    DAVPropStat dps = (DAVPropStat) ex.getReason();
1717:                    String msg = ex.getMessage();
1718:                    DAVPropStat stats[] = null;
1719:                    if (okdp.getNode().hasChildNodes()) {
1720:                        DAVPropStat okdps = DAVFactory.createPropStat(
1721:                                getStatusLine(HTTP.OK), okdp, document);
1722:                        stats = new DAVPropStat[2];
1723:                        stats[0] = okdps;
1724:                        stats[1] = dps;
1725:                    } else {
1726:                        stats = new DAVPropStat[1];
1727:                        stats[0] = dps;
1728:                    }
1729:                    // send ok properties and the one that failed
1730:                    throw new DAVPropertyException(msg, stats);
1731:                }
1732:                // everything is ok
1733:                if (okdp.getNode().hasChildNodes()) {
1734:                    return DAVFactory.createPropStat(getStatusLine(HTTP.OK),
1735:                            okdp, document);
1736:                }
1737:                return null;
1738:            }
1739:
1740:            protected void removeLiveProperty(DAVNode node, DAVProperties okdp,
1741:                    Document document) throws DAVPropertyException {
1742:                String name = node.getNode().getLocalName();
1743:                String value = node.getTextValue();
1744:                if (name.equals(DAVNode.DISPLAYNAME_NODE)) {
1745:                    setValue(ATTR_TITLE, "");
1746:                    okdp.addProperty(name);
1747:                } else if (name.equals(DAVNode.GETCONTENTLANGUAGE_NODE)) {
1748:                    setValue(ATTR_CONTENT_LANGUAGE, null);
1749:                    okdp.addProperty(name);
1750:                } else {
1751:                    // may be it's a dead "DAV:" property
1752:                    try {
1753:                        removeDeadProperty(node, okdp, document);
1754:                    } catch (DAVPropertyException ex) {
1755:                        DAVPropStat edps = DAVFactory.createPropStat(
1756:                                getStatusLine(HTTP.CONFLICT), name, document);
1757:                        throw new DAVPropertyException(name
1758:                                + " cannot be removed", edps);
1759:                    }
1760:                }
1761:            }
1762:
1763:            protected void removeDeadProperty(DAVNode node, DAVProperties okdp,
1764:                    Document document) throws DAVPropertyException {
1765:                Node n = node.getNode();
1766:                String name = n.getLocalName();
1767:                try {
1768:                    if (n.getNodeType() == n.ELEMENT_NODE) {
1769:                        Element el = (Element) n;
1770:                        removeDeadProperty(el);
1771:                        okdp.addNodeNS(document.importNode(el, false));
1772:                    } else {
1773:                        DAVPropStat dps = DAVFactory.createPropStatNS(
1774:                                getStatusLine(HTTP.CONFLICT), document
1775:                                        .importNode(n, false), document);
1776:                        String msg = "Invalid XML : " + name;
1777:                        throw new DAVPropertyException(msg, dps);
1778:                    }
1779:                } catch (DOMException ex) {
1780:                    DAVPropStat dps = DAVFactory.createPropStatNS(
1781:                            getStatusLine(HTTP.CONFLICT), document.importNode(
1782:                                    n, false), document);
1783:                    throw new DAVPropertyException(ex.getMessage(), dps);
1784:                }
1785:            }
1786:
1787:            /**
1788:             * Handle the PROPPATCH request.
1789:             * @param request the WEBDAV request
1790:             * @return a Reply instance
1791:             * @exception ProtocolException If processsing the request failed.
1792:             * @exception ResourceException If the resource got a fatal error.
1793:             */
1794:            public Reply proppatch(DAVRequest request)
1795:                    throws ProtocolException, ResourceException {
1796:                // prepare undo
1797:                Object oldvalues[] = this .values;
1798:                DAVBody body = getBody(request);
1799:                Document document = DAVBody
1800:                        .createDocument(DAVNode.MULTISTATUS_NODE);
1801:                DAVResponse dr = DAVFactory.createResponse(getURL(request)
1802:                        .getFile(),
1803:                //toExternalForm(), 
1804:                        document);
1805:                // attach the response to the document
1806:                document.getDocumentElement().appendChild(dr.getNode());
1807:
1808:                if (body != null) {
1809:                    DAVPropertyUpdate dpu = body.getPropertyUpdate();
1810:                    if (dpu != null) {
1811:                        DAVPropAction dpas[] = dpu.getActions();
1812:                        DAVPropStat dps = null;
1813:                        int len = dpas.length;
1814:                        try {
1815:                            for (int i = 0; i < len; i++) {
1816:                                DAVPropAction dpa = dpas[i];
1817:                                switch (dpa.getAction()) {
1818:                                case DAVPropAction.SET:
1819:                                    dps = setDAVProperties(dpa.getProperties(),
1820:                                            document);
1821:                                    break;
1822:                                case DAVPropAction.REMOVE:
1823:                                    dps = removeDAVProperties(dpa
1824:                                            .getProperties(), document);
1825:                                    break;
1826:                                default:
1827:                                    // error
1828:                                    Reply error = request
1829:                                            .makeReply(HTTP.BAD_REQUEST);
1830:                                    error.setContent("Invalid request");
1831:                                    throw new HTTPException(error);
1832:                                }
1833:                                if (dps != null) {
1834:                                    dr.addDAVNode(dps);
1835:                                }
1836:                            }
1837:                            saveDeadProperties();
1838:                        } catch (DAVPropertyException ex) {
1839:                            // stop all an undo change
1840:                            reloadDeadProperties();
1841:                            this .values = oldvalues;
1842:                            // report error
1843:                            DAVPropStat dpss[] = (DAVPropStat[]) ex.getReason();
1844:                            for (int j = 0; j < dpss.length; j++) {
1845:                                dr.addDAVNode(dpss[j]);
1846:                            }
1847:                            dr.setDescription(ex.getMessage());
1848:                        }
1849:                        return createDAVReply(request, WEBDAV.MULTI_STATUS,
1850:                                document);
1851:                    }
1852:                }
1853:                Reply error = request.makeReply(HTTP.BAD_REQUEST);
1854:                error.setContent("Invalid request");
1855:                throw new HTTPException(error);
1856:            }
1857:
1858:            /**
1859:             * Handle the MKCOL request.
1860:             * @param request the WEBDAV request
1861:             * @return a Reply instance
1862:             * @exception ProtocolException If processsing the request failed.
1863:             * @exception ResourceException If the resource got a fatal error.
1864:             */
1865:            public Reply mkcol(DAVRequest request) throws ProtocolException,
1866:                    ResourceException {
1867:                if (dresource != null) {
1868:                    String newcol = (String) request.getState(REMAINING_PATH);
1869:                    if (newcol != null) {
1870:                        if (dresource.getExtensibleFlag() && getPutableFlag()) {
1871:                            // create a new collection
1872:                            ResourceReference rr = dresource
1873:                                    .createDirectoryResource(newcol);
1874:                            if (rr == null) {
1875:                                Reply error = request
1876:                                        .makeReply(HTTP.UNSUPPORTED_MEDIA_TYPE);
1877:                                error.setContent("Failed to create collection "
1878:                                        + newcol);
1879:                                throw new HTTPException(error);
1880:                            } else {
1881:                                Reply reply = request.makeReply(HTTP.CREATED);
1882:                                reply.setContent("<P>Collection " + newcol
1883:                                        + " succesfully created");
1884:
1885:                                return reply;
1886:                            }
1887:                        } else {
1888:                            Reply error = request.makeReply(HTTP.FORBIDDEN);
1889:                            error
1890:                                    .setContent("The server doen't allow collection "
1891:                                            + "creation here.");
1892:                            throw new HTTPException(error);
1893:                        }
1894:                    } else {
1895:                        Reply error = request.makeReply(HTTP.NOT_ALLOWED);
1896:                        error.setContent(dresource.getIdentifier()
1897:                                + " already exists!");
1898:                        throw new HTTPException(error);
1899:                    }
1900:                } else {
1901:                    Reply error = request.makeReply(HTTP.NOT_ALLOWED);
1902:                    error.setContent(dresource.getIdentifier()
1903:                            + " already exists!");
1904:                    throw new HTTPException(error);
1905:                }
1906:            }
1907:
1908:            protected org.w3c.www.protocol.webdav.DAVRequest createRequest(
1909:                    DAVRequest req, String mtd, URL url, Hashtable headers,
1910:                    InputStream in) {
1911:                org.w3c.www.protocol.webdav.DAVRequest request = null;
1912:                request = manager.createDAVRequest();
1913:                request.setURL(url);
1914:                request.setMethod(mtd);
1915:                if (req.hasAuthorization()) {
1916:                    request.setAuthorization(req.getAuthorization());
1917:                }
1918:                if (headers != null) {
1919:                    Enumeration keys = headers.keys();
1920:                    while (keys.hasMoreElements()) {
1921:                        String header = (String) keys.nextElement();
1922:                        String value = (String) headers.get(header);
1923:                        request.setValue(header, value);
1924:                    }
1925:                }
1926:                if (in != null) {
1927:                    request.setOutputStream(in);
1928:                }
1929:                return request;
1930:            }
1931:
1932:            protected org.w3c.www.protocol.webdav.DAVRequest createRequest(
1933:                    DAVRequest request, String mtd, URL url, Hashtable headers) {
1934:                return createRequest(request, mtd, url, headers,
1935:                        (InputStream) null);
1936:            }
1937:
1938:            protected org.w3c.www.protocol.webdav.DAVRequest createRequest(
1939:                    DAVRequest request, String mtd, URL url, Hashtable headers,
1940:                    Document document) {
1941:                if (document != null) {
1942:                    ByteArrayOutputStream out = new ByteArrayOutputStream();
1943:
1944:                    OutputFormat format = new OutputFormat(document,
1945:                            WEBDAV.ENCODING, true);
1946:                    format.setOmitXMLDeclaration(false);
1947:                    format.setPreserveSpace(false);
1948:                    XMLSerializer serializer = new XMLSerializer(out, format);
1949:                    try {
1950:                        serializer.serialize(document);
1951:                    } catch (IOException ex) {
1952:                        ex.printStackTrace();
1953:                    }
1954:
1955:                    int len = out.size();
1956:                    if (headers == null) {
1957:                        headers = new Hashtable();
1958:                    }
1959:                    headers.put("Content-Length", String.valueOf(len));
1960:                    headers.put("Content-Type", xmlcontenttype.toString());
1961:                    InputStream in = new ByteArrayInputStream(out.toByteArray());
1962:                    return createRequest(request, mtd, url, headers, in);
1963:                } else {
1964:                    return createRequest(request, mtd, url, headers,
1965:                            (InputStream) null);
1966:                }
1967:            }
1968:
1969:            protected DAVRequest createInternalRequest(DAVRequest request,
1970:                    String mtd, URL url, Hashtable headers, Document document) {
1971:                if (document != null) {
1972:                    ByteArrayOutputStream out = new ByteArrayOutputStream();
1973:
1974:                    OutputFormat format = new OutputFormat(document,
1975:                            WEBDAV.ENCODING, true);
1976:                    format.setOmitXMLDeclaration(false);
1977:                    format.setPreserveSpace(false);
1978:                    XMLSerializer serializer = new XMLSerializer(out, format);
1979:                    try {
1980:                        serializer.serialize(document);
1981:                    } catch (IOException ex) {
1982:                        ex.printStackTrace();
1983:                    }
1984:
1985:                    int len = out.size();
1986:                    if (headers == null) {
1987:                        headers = new Hashtable();
1988:                    }
1989:                    headers.put("Content-Length", String.valueOf(len));
1990:                    headers.put("Content-Type", xmlcontenttype.toString());
1991:                    InputStream in = new ByteArrayInputStream(out.toByteArray());
1992:                    return createInternalRequest(request, mtd, url, headers, in);
1993:                } else {
1994:                    return createInternalRequest(request, mtd, url, headers,
1995:                            (InputStream) null);
1996:                }
1997:            }
1998:
1999:            /**
2000:             * Should be called to purge the reply, otherwise the connection won't
2001:             * be marked idle and won't be reused.
2002:             * @param reply the reply to purge.
2003:             */
2004:            protected void skipBody(org.w3c.www.protocol.webdav.DAVReply reply) {
2005:                try {
2006:                    if (reply.hasInputStream()) {
2007:                        InputStream in = reply.getInputStream();
2008:                        byte buffer[] = new byte[256];
2009:                        try {
2010:                            if (debug) {
2011:                                System.out.println(">>> skipping body <<<<");
2012:                                int nb = -1;
2013:                                while ((nb = in.read(buffer)) != -1) {
2014:                                    System.out.print(new String(buffer, 0, nb));
2015:                                }
2016:                                System.out.println(">>> end body <<<<\n");
2017:                            } else {
2018:                                while (in.read(buffer) != -1)
2019:                                    ;
2020:                            }
2021:                        } catch (IOException ioex) {
2022:                            try {
2023:                                in.close();
2024:                            } catch (IOException ioex2) {
2025:                            }
2026:                        }
2027:                    }
2028:                } catch (IOException ex) {
2029:                    //nothing to do
2030:                }
2031:            }
2032:
2033:            protected void closeInternalReply(DAVReply reply) {
2034:                if (reply.hasStream()) {
2035:                    try {
2036:                        reply.openStream().close();
2037:                        reply.setStream((InputStream) null);
2038:                        reply.setContentLength(0);
2039:                    } catch (IOException ex) {
2040:                    }
2041:                }
2042:            }
2043:
2044:            protected DAVRequest createInternalRequest(DAVRequest req,
2045:                    String mtd, URL url, Hashtable headers, InputStream in) {
2046:                DAVRequest request;
2047:                request = (DAVRequest) req.getClone();
2048:                request.setURL(url);
2049:                request.setMethod(mtd);
2050:                if (req.hasAuthorization()) {
2051:                    request.setAuthorization(req.getAuthorization());
2052:                }
2053:                if (headers != null) {
2054:                    Enumeration keys = headers.keys();
2055:                    while (keys.hasMoreElements()) {
2056:                        String header = (String) keys.nextElement();
2057:                        String value = (String) headers.get(header);
2058:                        request.setValue(header, value);
2059:                    }
2060:                }
2061:                if (in != null) {
2062:                    request.setStream(in);
2063:                }
2064:                request.setInternal(true);
2065:                return request;
2066:            }
2067:
2068:            protected DAVRequest createInternalRequest(DAVRequest req,
2069:                    String mtd, URL url, Hashtable headers) {
2070:                return createInternalRequest(req, mtd, url, headers,
2071:                        (InputStream) null);
2072:            }
2073:
2074:            private Reply internalCopy(DAVRequest request, URL dst)
2075:                    throws ProtocolException, ResourceException {
2076:                DAVRequest req;
2077:                DAVReply rep;
2078:                req = createInternalRequest(request, "HEAD", dst, null);
2079:                try {
2080:                    rep = (DAVReply) getServer().perform(req);
2081:                    closeInternalReply(rep);
2082:                } catch (Exception ex) {
2083:                    Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
2084:                    error.setContent(ex.getMessage());
2085:                    throw new HTTPException(error);
2086:                }
2087:                boolean overwrite = false;
2088:                if (rep.getStatus() != HTTP.NOT_FOUND) {
2089:                    overwrite = request.getOverwrite();
2090:                    if (!overwrite) {
2091:                        // 412 Precondition failed
2092:                        String msg = "The state of the destination is non-null";
2093:                        Reply error = request
2094:                                .makeReply(HTTP.PRECONDITION_FAILED);
2095:                        error.setContent(msg);
2096:                        return error;
2097:                    } else {
2098:                        // overwrite but DELETE before
2099:                        req = createInternalRequest(request, "DELETE", dst,
2100:                                null);
2101:                        try {
2102:                            rep = (DAVReply) getServer().perform(req);
2103:                            closeInternalReply(rep);
2104:                        } catch (Exception ex) {
2105:                            Reply error = request
2106:                                    .makeReply(HTTP.INTERNAL_SERVER_ERROR);
2107:                            error.setContent(ex.getMessage());
2108:                            throw new HTTPException(error);
2109:                        }
2110:                        // silent error, if delete failed try to overwrite...
2111:                    }
2112:                }
2113:                // ok, perform the real copy now
2114:                if (isCollection()) {
2115:                    return internalCopyCollection(dst, request, overwrite);
2116:                } else {
2117:                    return internalCopyResource(dst, request, overwrite);
2118:                }
2119:            }
2120:
2121:            /**
2122:             * Handle the COPY request.
2123:             * @param request the WEBDAV request
2124:             * @return a Reply instance
2125:             * @exception ProtocolException If processsing the request failed.
2126:             * @exception ResourceException If the resource got a fatal error.
2127:             */
2128:            public Reply copy(DAVRequest request) throws ProtocolException,
2129:                    ResourceException {
2130:                String dest = request.getDestination();
2131:                URL src = getURL(request);
2132:                URL dst = null;
2133:                try {
2134:                    dst = new URL(dest);
2135:                } catch (MalformedURLException ex) {
2136:                    Reply error = request.makeReply(HTTP.BAD_REQUEST);
2137:                    error.setContent("Invalid destination URL");
2138:                    throw new HTTPException(error);
2139:                }
2140:                // check that we're not going to copy on ourself
2141:                if (dst.equals(src)) {
2142:                    // 403 Forbidden
2143:                    Reply error = request.makeReply(HTTP.FORBIDDEN);
2144:                    String msg = "The source and destination URIs are the same";
2145:                    error.setContent(msg);
2146:                    return error;
2147:                }
2148:                // is this local?
2149:                if (URLUtils.equalsProtocolHostPort(src, dst)) {
2150:                    // yes, use only internal calls
2151:                    return internalCopy(request, dst);
2152:                }
2153:                // not local, use remote access procedure
2154:
2155:                // check for overwrite
2156:                org.w3c.www.protocol.webdav.DAVRequest crequest = null;
2157:                org.w3c.www.protocol.webdav.DAVReply creply = null;
2158:                crequest = createRequest(request, "HEAD", dst, null);
2159:                try {
2160:                    creply = manager.runDAVRequest(crequest);
2161:                    skipBody(creply);
2162:                } catch (org.w3c.www.protocol.http.HttpException ex) {
2163:                    Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
2164:                    error.setContent(ex.getMessage());
2165:                    throw new HTTPException(error);
2166:                }
2167:                boolean overwrite = false;
2168:                if (creply.getStatus() != HTTP.NOT_FOUND) {
2169:                    overwrite = request.getOverwrite();
2170:                    if (!overwrite) {
2171:                        // 412 Precondition failed
2172:                        String msg = "The state of the destination is non-null";
2173:                        Reply error = request
2174:                                .makeReply(HTTP.PRECONDITION_FAILED);
2175:                        error.setContent(msg);
2176:                        return error;
2177:                    } else {
2178:                        // overwrite but DELETE before
2179:                        crequest = createRequest(request, "DELETE", dst, null);
2180:                        try {
2181:                            creply = manager.runDAVRequest(crequest);
2182:                            skipBody(creply);
2183:                        } catch (org.w3c.www.protocol.http.HttpException ex) {
2184:                            Reply error = request
2185:                                    .makeReply(HTTP.INTERNAL_SERVER_ERROR);
2186:                            error.setContent(ex.getMessage());
2187:                            throw new HTTPException(error);
2188:                        }
2189:                        // silent error, if delete failed try to overwrite...
2190:                    }
2191:                }
2192:                // ok, perform the real copy now
2193:                if (isCollection()) {
2194:                    return copyCollection(dst, request, overwrite);
2195:                } else {
2196:                    return copyResource(dst, request, overwrite);
2197:                }
2198:            }
2199:
2200:            /**
2201:             * Kind of proxying the reply but only for headers.
2202:             */
2203:            protected Reply dupReply(DAVRequest request,
2204:                    org.w3c.www.protocol.webdav.DAVReply rep, boolean created) {
2205:                Reply reply = null;
2206:                if (created) {
2207:                    reply = request.makeReply(HTTP.NO_CONTENT);
2208:                    return reply;
2209:                } else {
2210:                    reply = request.makeReply(rep.getStatus());
2211:                }
2212:                reply.setHeaderValue(Reply.H_SERVER, null);
2213:                Enumeration e = rep.enumerateHeaderDescriptions();
2214:                while (e.hasMoreElements()) {
2215:                    HeaderDescription d = (HeaderDescription) e.nextElement();
2216:                    HeaderValue v = rep.getHeaderValue(d);
2217:                    if (v != null)
2218:                        reply.setHeaderValue(d, v);
2219:                }
2220:                reply.setContentLength(0);
2221:                reply.setHeaderValue(Reply.H_CONNECTION, null);
2222:                reply.setHeaderValue(Reply.H_PROXY_CONNECTION, null);
2223:                reply.setHeaderValue(Reply.H_PUBLIC, null);
2224:                reply.setHeaderValue(Reply.H_TRANSFER_ENCODING, null);
2225:                reply.setHeaderValue(Reply.H_UPGRADE, null);
2226:                reply.setHeaderValue(Reply.H_CONTENT_TYPE, null);
2227:                reply.removeHeader("keep-alive");
2228:                return reply;
2229:            }
2230:
2231:            /**
2232:             * Handle the COPY request for a collection
2233:             * @param dst the destination URL
2234:             * @param request the WEBDAV request
2235:             * @return a Reply instance
2236:             * @exception ProtocolException If processsing the request failed.
2237:             * @exception ResourceException If the resource got a fatal error.
2238:             */
2239:            protected Reply copyCollection(URL destination, DAVRequest request,
2240:                    boolean overwrite) throws ProtocolException,
2241:                    ResourceException {
2242:                DAVBody body = getBody(request);
2243:                Document document = DAVBody
2244:                        .createDocument(DAVNode.MULTISTATUS_NODE);
2245:                Reply reply = null;
2246:                try {
2247:                    return copyCollection(destination, request, overwrite,
2248:                            body, document);
2249:                } catch (MultiStatusException ex) {
2250:                    return createDAVReply(request, WEBDAV.MULTI_STATUS, ex
2251:                            .getDocument());
2252:                }
2253:            }
2254:
2255:            /**
2256:             * Handle the COPY request for a collection
2257:             * @param dst the destination URL
2258:             * @param request the WEBDAV request
2259:             * @return a Reply instance
2260:             * @exception ProtocolException If processsing the request failed.
2261:             * @exception ResourceException If the resource got a fatal error.
2262:             */
2263:            private Reply internalCopyCollection(URL destination,
2264:                    DAVRequest request, boolean overwrite)
2265:                    throws ProtocolException, ResourceException {
2266:                DAVBody body = getBody(request);
2267:                Document document = DAVBody
2268:                        .createDocument(DAVNode.MULTISTATUS_NODE);
2269:                Reply reply = null;
2270:                try {
2271:                    return internalCopyCollection(destination, request,
2272:                            overwrite, body, document);
2273:                } catch (MultiStatusException ex) {
2274:                    return createDAVReply(request, WEBDAV.MULTI_STATUS, ex
2275:                            .getDocument());
2276:                }
2277:            }
2278:
2279:            protected Reply copyCollection(URL destination, DAVRequest request,
2280:                    boolean overwrite, DAVBody body, Document document)
2281:                    throws ProtocolException, ResourceException,
2282:                    MultiStatusException {
2283:                // first copy myself
2284:                // MKCOL
2285:                org.w3c.www.protocol.webdav.DAVRequest crequest = null;
2286:                org.w3c.www.protocol.webdav.DAVReply creply = null;
2287:                crequest = createRequest(request, "MKCOL", destination, null);
2288:                try {
2289:                    creply = manager.runDAVRequest(crequest);
2290:                    skipBody(creply);
2291:                } catch (org.w3c.www.protocol.http.HttpException ex) {
2292:                    Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
2293:                    error.setContent(ex.getMessage());
2294:                    throw new HTTPException(error);
2295:                }
2296:                if (creply.getStatus() != HTTP.CREATED) {
2297:                    return dupReply(request, creply, false);
2298:                }
2299:                org.w3c.www.protocol.webdav.DAVReply mkcolreply = creply;
2300:                // Copy Properties
2301:                copyProperties(request, destination, body);
2302:                // CHILDREN? (Depth can only be 0 or infinity see RFC 2518 - 8.8.3)
2303:                if (request.getDepth() == 0) {
2304:                    // only me so return
2305:                    return dupReply(request, creply, overwrite);
2306:                } else {
2307:                    // XML Document
2308:                    DAVMultiStatus dms = DAVFactory.createMultiStatus(document
2309:                            .getDocumentElement());
2310:                    boolean multistatus = false;
2311:                    // Children resource
2312:                    Enumeration e = dresource.enumerateResourceIdentifiers();
2313:                    ResourceReference rr = null;
2314:                    FramedResource fr = null;
2315:                    while (e.hasMoreElements()) {
2316:                        String name = (String) e.nextElement();
2317:                        rr = dresource.lookup(name);
2318:                        if (rr != null) {
2319:                            try {
2320:                                fr = (FramedResource) rr.lock();
2321:                                if (fr == resource) { // for root
2322:                                    continue;
2323:                                }
2324:                                DAVFrame df = (DAVFrame) fr
2325:                                        .getFrame(DAVFrame.class);
2326:                                URL dest = null;
2327:                                if (df != null) {
2328:                                    try {
2329:                                        dest = computeDestURL(destination, df);
2330:                                    } catch (MalformedURLException ex) {
2331:                                        Reply error = request
2332:                                                .makeReply(HTTP.INTERNAL_SERVER_ERROR);
2333:                                        String msg = "Can't build destination URI : "
2334:                                                + ex.getMessage();
2335:                                        error.setContent(msg);
2336:                                        throw new HTTPException(error);
2337:                                    }
2338:                                    if (df.isCollection()) {
2339:                                        try {
2340:                                            // silent success
2341:                                            df.copyCollection(dest, request,
2342:                                                    overwrite, body, document);
2343:                                        } catch (MultiStatusException ex) {
2344:                                            multistatus = true;
2345:                                            ex.printStackTrace();
2346:                                            ex.addResponses(document, dms);
2347:                                        }
2348:                                    } else {
2349:                                        try {
2350:                                            // silent success
2351:                                            df.copyDAVResource(request, df
2352:                                                    .getURL(request), dest,
2353:                                                    body);
2354:                                        } catch (MultiStatusException ex) {
2355:                                            multistatus = true;
2356:                                            ex.printStackTrace();
2357:                                            // add to multistatus node
2358:                                            ex.addResponses(document, dms);
2359:                                        }
2360:                                    }
2361:                                } else {
2362:                                    // what should I do there?
2363:                                    // nothing I guess
2364:                                }
2365:                            } catch (InvalidResourceException ex) {
2366:                                // build error response?
2367:                            } finally {
2368:                                rr.unlock();
2369:                            }
2370:                        }
2371:                    }
2372:                    if (multistatus) {
2373:                        throw new MultiStatusException(document);
2374:                    } else {
2375:                        return dupReply(request, mkcolreply, overwrite);
2376:                    }
2377:                }
2378:            }
2379:
2380:            protected Reply internalCopyCollection(URL destination,
2381:                    DAVRequest request, boolean overwrite, DAVBody body,
2382:                    Document document) throws ProtocolException,
2383:                    ResourceException, MultiStatusException {
2384:                // first copy myself
2385:                // MKCOL
2386:                DAVRequest crequest = null;
2387:                DAVReply creply = null;
2388:                crequest = createInternalRequest(request, "MKCOL", destination,
2389:                        null);
2390:                try {
2391:                    creply = (DAVReply) getServer().perform(crequest);
2392:                    closeInternalReply(creply);
2393:                } catch (Exception ex) {
2394:                    Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
2395:                    error.setContent(ex.getMessage());
2396:                    throw new HTTPException(error);
2397:                }
2398:                if (creply.getStatus() != HTTP.CREATED) {
2399:                    return creply;
2400:                }
2401:                DAVReply mkcolreply = creply;
2402:                // Copy Properties
2403:                internalCopyProperties(request, destination, body);
2404:                // CHILDREN? (Depth can only be 0 or infinity see RFC 2518 - 8.8.3)
2405:                if (request.getDepth() == 0) {
2406:                    // only me so return
2407:                    if (overwrite) {
2408:                        creply.setStatus(HTTP.NO_CONTENT);
2409:                    }
2410:                    return creply;
2411:                } else {
2412:                    // XML Document
2413:                    DAVMultiStatus dms = DAVFactory.createMultiStatus(document
2414:                            .getDocumentElement());
2415:                    boolean multistatus = false;
2416:                    // Children resource
2417:                    Enumeration e = dresource.enumerateResourceIdentifiers();
2418:                    ResourceReference rr = null;
2419:                    FramedResource fr = null;
2420:                    while (e.hasMoreElements()) {
2421:                        String name = (String) e.nextElement();
2422:                        rr = dresource.lookup(name);
2423:                        if (rr != null) {
2424:                            try {
2425:                                fr = (FramedResource) rr.lock();
2426:                                if (fr == resource) { // for root
2427:                                    continue;
2428:                                }
2429:                                DAVFrame df = (DAVFrame) fr
2430:                                        .getFrame(DAVFrame.class);
2431:                                URL dest = null;
2432:                                if (df != null) {
2433:                                    try {
2434:                                        dest = computeDestURL(destination, df);
2435:                                    } catch (MalformedURLException ex) {
2436:                                        Reply error = request
2437:                                                .makeReply(HTTP.INTERNAL_SERVER_ERROR);
2438:                                        String msg = "Can't build destination URI : "
2439:                                                + ex.getMessage();
2440:                                        error.setContent(msg);
2441:                                        throw new HTTPException(error);
2442:                                    }
2443:                                    if (df.isCollection()) {
2444:                                        try {
2445:                                            // silent success
2446:                                            df.internalCopyCollection(dest,
2447:                                                    request, overwrite, body,
2448:                                                    document);
2449:                                        } catch (MultiStatusException ex) {
2450:                                            multistatus = true;
2451:                                            ex.printStackTrace();
2452:                                            ex.addResponses(document, dms);
2453:                                        }
2454:                                    } else {
2455:                                        try {
2456:                                            // silent success
2457:                                            df.internalCopyDAVResource(request,
2458:                                                    df.getURL(request), dest,
2459:                                                    body);
2460:                                        } catch (MultiStatusException ex) {
2461:                                            multistatus = true;
2462:                                            ex.printStackTrace();
2463:                                            // add to multistatus node
2464:                                            ex.addResponses(document, dms);
2465:                                        }
2466:                                    }
2467:                                } else {
2468:                                    // what should I do there?
2469:                                    // nothing I guess
2470:                                }
2471:                            } catch (InvalidResourceException ex) {
2472:                                // build error response?
2473:                            } finally {
2474:                                rr.unlock();
2475:                            }
2476:                        }
2477:                    }
2478:                    if (multistatus) {
2479:                        throw new MultiStatusException(document);
2480:                    } else {
2481:                        if (overwrite) {
2482:                            mkcolreply.setStatus(HTTP.NO_CONTENT);
2483:                        }
2484:                        return mkcolreply;
2485:                    }
2486:                }
2487:            }
2488:
2489:            protected URL computeDestURL(URL parent, DAVFrame df)
2490:                    throws MalformedURLException {
2491:                String file = parent.getFile();
2492:                StringBuffer buffer = new StringBuffer(file);
2493:                if (!file.endsWith("/")) {
2494:                    buffer.append("/");
2495:                }
2496:                buffer.append(df.getResource().getIdentifier());
2497:                if (df.isCollection()) {
2498:                    buffer.append("/");
2499:                }
2500:                return new URL(parent, buffer.toString());
2501:            }
2502:
2503:            /**
2504:             * Handle the COPY request for a simple resource (not a collection)
2505:             * @param dst the destination URL
2506:             * @param request the WEBDAV request
2507:             * @return a Reply instance
2508:             * @exception ProtocolException If processsing the request failed.
2509:             * @exception ResourceException If the resource got a fatal error.
2510:             */
2511:            protected Reply copyResource(URL dst, DAVRequest request,
2512:                    boolean overwrite) throws ProtocolException,
2513:                    ResourceException {
2514:                try {
2515:                    URL src = getURL(request);
2516:                    org.w3c.www.protocol.webdav.DAVReply reply = copyDAVResource(
2517:                            request, src, dst, getBody(request));
2518:                    if (overwrite) {
2519:                        reply.setStatus(HTTP.NO_CONTENT);
2520:                    }
2521:                    return dupReply(request, reply, overwrite);
2522:                } catch (MultiStatusException ex) {
2523:                    return createDAVReply(request, WEBDAV.MULTI_STATUS, ex
2524:                            .getDocument());
2525:                }
2526:            }
2527:
2528:            protected org.w3c.www.protocol.webdav.DAVReply copyDAVResource(
2529:                    DAVRequest req, URL source, URL destination, DAVBody body)
2530:                    throws MultiStatusException {
2531:                DAVResponse dr = null;
2532:                org.w3c.www.protocol.webdav.DAVRequest request = null;
2533:                org.w3c.www.protocol.webdav.DAVReply reply = null;
2534:                // perform the PUT request to send the body.
2535:                // headers
2536:                Hashtable headers = new Hashtable();
2537:                headers.put("Content-Length", String
2538:                        .valueOf(getContentLength()));
2539:                headers.put("Content-Type", getContentType().toString());
2540:                // body
2541:                InputStream in = null;
2542:                try {
2543:                    in = new FileInputStream(fresource.getFile());
2544:                } catch (IOException ex) {
2545:                    // error that should not occurs
2546:                    String msg = "Cannot read source file";
2547:                    throw new MultiStatusException(
2548:                            destination.toExternalForm(),
2549:                            getStatusLine(HTTP.INTERNAL_SERVER_ERROR), msg);
2550:                }
2551:                request = createRequest(req, "PUT", destination, headers, in);
2552:                try {
2553:                    reply = manager.runDAVRequest(request);
2554:                    skipBody(reply);
2555:                } catch (org.w3c.www.protocol.http.HttpException ex) {
2556:                    throw new MultiStatusException(
2557:                            destination.toExternalForm(),
2558:                            getStatusLine(HTTP.INTERNAL_SERVER_ERROR), ex
2559:                                    .getMessage());
2560:                }
2561:                int putstatus = reply.getStatus();
2562:                org.w3c.www.protocol.webdav.DAVReply putreply = reply;
2563:                if (putstatus / 100 != 2) {
2564:                    // error
2565:                    throw new MultiStatusException(
2566:                            destination.toExternalForm(),
2567:                            getStatusLine(putstatus));
2568:                }
2569:                // now update properties
2570:                copyProperties(req, destination, body);
2571:                // done
2572:                return putreply;
2573:            }
2574:
2575:            /**
2576:             * Handle the COPY request for a simple resource (not a collection)
2577:             * @param dst the destination URL
2578:             * @param request the WEBDAV request
2579:             * @return a Reply instance
2580:             * @exception ProtocolException If processsing the request failed.
2581:             * @exception ResourceException If the resource got a fatal error.
2582:             */
2583:            protected Reply internalCopyResource(URL dst, DAVRequest request,
2584:                    boolean overwrite) throws ProtocolException,
2585:                    ResourceException {
2586:                try {
2587:                    URL src = getURL(request);
2588:                    DAVReply reply = internalCopyDAVResource(request, src, dst,
2589:                            getBody(request));
2590:                    if (overwrite) {
2591:                        reply.setStatus(HTTP.NO_CONTENT);
2592:                    }
2593:                    return reply;
2594:                } catch (MultiStatusException ex) {
2595:                    return createDAVReply(request, WEBDAV.MULTI_STATUS, ex
2596:                            .getDocument());
2597:                }
2598:            }
2599:
2600:            protected DAVReply internalCopyDAVResource(DAVRequest req,
2601:                    URL source, URL destination, DAVBody body)
2602:                    throws MultiStatusException {
2603:                DAVResponse dr = null;
2604:                DAVRequest request = null;
2605:                DAVReply reply = null;
2606:                // perform the PUT request to send the body.
2607:                // headers
2608:                Hashtable headers = new Hashtable();
2609:                headers.put("Content-Length", String
2610:                        .valueOf(getContentLength()));
2611:                headers.put("Content-Type", getContentType().toString());
2612:                // body
2613:                InputStream in = null;
2614:                try {
2615:                    in = new FileInputStream(fresource.getFile());
2616:                } catch (IOException ex) {
2617:                    // error that should not occurs
2618:                    String msg = "Cannot read source file";
2619:                    throw new MultiStatusException(
2620:                            destination.toExternalForm(),
2621:                            getStatusLine(HTTP.INTERNAL_SERVER_ERROR), msg);
2622:                }
2623:                request = createInternalRequest(req, "PUT", destination,
2624:                        headers, in);
2625:                try {
2626:                    reply = (DAVReply) getServer().perform(request);
2627:                    closeInternalReply(reply);
2628:                } catch (Exception ex) {
2629:                    throw new MultiStatusException(
2630:                            destination.toExternalForm(),
2631:                            getStatusLine(HTTP.INTERNAL_SERVER_ERROR), ex
2632:                                    .getMessage());
2633:                }
2634:                int putstatus = reply.getStatus();
2635:                DAVReply putreply = reply;
2636:                if (putstatus / 100 != 2) {
2637:                    // error
2638:                    throw new MultiStatusException(
2639:                            destination.toExternalForm(),
2640:                            getStatusLine(putstatus));
2641:                }
2642:                // now update properties
2643:                internalCopyProperties(req, destination, body);
2644:                // done
2645:                return putreply;
2646:            }
2647:
2648:            protected void copyProperties(DAVRequest req, URL destination,
2649:                    DAVBody body) throws MultiStatusException {
2650:                org.w3c.www.protocol.webdav.DAVRequest request = null;
2651:                org.w3c.www.protocol.webdav.DAVReply reply = null;
2652:                // first try to copy all properties
2653:                Document document = DAVBody
2654:                        .createDocument(DAVNode.PROPERTYUPDATE_NODE);
2655:                DAVPropAction dpa = DAVFactory.createPropAction(
2656:                        DAVPropAction.SET, getPropertiesForCopy(document),
2657:                        document);
2658:                document.getDocumentElement().appendChild(dpa.getNode());
2659:                request = createRequest(req, "PROPPATCH", destination, null,
2660:                        document);
2661:                try {
2662:                    reply = manager.runDAVRequest(request);
2663:                    skipBody(reply);
2664:                } catch (org.w3c.www.protocol.http.HttpException ex) {
2665:                    throw new MultiStatusException(
2666:                            destination.toExternalForm(),
2667:                            getStatusLine(HTTP.INTERNAL_SERVER_ERROR), ex
2668:                                    .getMessage());
2669:                }
2670:                // check with keepalive flag
2671:                // FIXME
2672:                if (body != null) {
2673:                    DAVPropertyBehavior dpb = body.getPropertyBehavior();
2674:                    if ((dpb != null) && (!dpb.omit())) {
2675:                        if (dpb.keepaliveAll()) {
2676:
2677:                        } else {
2678:                            String properties[] = dpb.getHrefs();
2679:                        }
2680:                    } else {
2681:
2682:                    }
2683:                }
2684:            }
2685:
2686:            protected void internalCopyProperties(DAVRequest req,
2687:                    URL destination, DAVBody body) throws MultiStatusException {
2688:                DAVRequest request = null;
2689:                DAVReply reply = null;
2690:                // first try to copy all properties
2691:                Document document = DAVBody
2692:                        .createDocument(DAVNode.PROPERTYUPDATE_NODE);
2693:                DAVPropAction dpa = DAVFactory.createPropAction(
2694:                        DAVPropAction.SET, getPropertiesForCopy(document),
2695:                        document);
2696:                document.getDocumentElement().appendChild(dpa.getNode());
2697:                request = createInternalRequest(req, "PROPPATCH", destination,
2698:                        null, document);
2699:                try {
2700:
2701:                    reply = (DAVReply) getServer().perform(request);
2702:                    closeInternalReply(reply);
2703:                } catch (Exception ex) {
2704:                    throw new MultiStatusException(
2705:                            destination.toExternalForm(),
2706:                            getStatusLine(HTTP.INTERNAL_SERVER_ERROR), ex
2707:                                    .getMessage());
2708:                }
2709:                // check with keepalive flag
2710:                // FIXME
2711:                if (body != null) {
2712:                    DAVPropertyBehavior dpb = body.getPropertyBehavior();
2713:                    if ((dpb != null) && (!dpb.omit())) {
2714:                        if (dpb.keepaliveAll()) {
2715:
2716:                        } else {
2717:                            String properties[] = dpb.getHrefs();
2718:                        }
2719:                    } else {
2720:
2721:                    }
2722:                }
2723:            }
2724:
2725:            /**
2726:             * Handle the MOVE request.
2727:             * @param request the WEBDAV request
2728:             * @return a Reply instance
2729:             * @exception ProtocolException If processsing the request failed.
2730:             * @exception ResourceException If the resource got a fatal error.
2731:             */
2732:            public Reply move(DAVRequest request) throws ProtocolException,
2733:                    ResourceException {
2734:                // check that we can be deleted
2735:                if (getAllowDeleteFlag()) {
2736:                    Reply reply = copy(request);
2737:                    int status = reply.getStatus();
2738:                    if (status == HTTP.NO_CONTENT || status == HTTP.CREATED) {
2739:                        delete(request);
2740:                        return reply;
2741:                    } else {
2742:                        return reply;
2743:                    }
2744:                }
2745:                Reply error = request.makeReply(HTTP.NOT_ALLOWED);
2746:                error.setContent("Method MOVE not allowed.");
2747:                error.setHeaderValue(Reply.H_ALLOW, getAllow());
2748:                throw new HTTPException(error);
2749:            }
2750:
2751:            protected synchronized String getNewLockToken() {
2752:                return "opaquelocktoken:"
2753:                        + (new org.w3c.util.UUID()).toString();
2754:            }
2755:
2756:            /**
2757:             * Handle the LOCK request.
2758:             * @param request the WEBDAV request
2759:             * @return a Reply instance
2760:             * @exception ProtocolException If processsing the request failed.
2761:             * @exception ResourceException If the resource got a fatal error.
2762:             */
2763:            public synchronized Reply lock(DAVRequest request)
2764:                    throws ProtocolException, ResourceException {
2765:                DAVBody body = getBody(request);
2766:                if (body == null) { // refresh?
2767:                    if (debug) {
2768:                        System.out.println(">>> Refreshing lock...");
2769:                    }
2770:                    refreshLock(request.getTimeout());
2771:                    Document doc = DAVBody.createDocument(DAVNode.PROP_NODE);
2772:                    addLockDiscovery(request, doc.getDocumentElement());
2773:                    Reply ok = createDAVReply(request, HTTP.OK, doc);
2774:                    return ok;
2775:                } else { // real new lock
2776:                    String timeouts[] = request.getTimeout();
2777:                    DAVLockInfo lockinfo = body.getLockInfo();
2778:                    if (lockinfo != null) {
2779:                        Node owner = lockinfo.getOwner();
2780:                        lock(getNewLockToken(), request.getDepth(), request
2781:                                .getTimeout(), (String) request
2782:                                .getState(AuthFilter.STATE_AUTHUSER), owner);
2783:                        Document doc = DAVBody
2784:                                .createDocument(DAVNode.PROP_NODE);
2785:                        addLockDiscovery(request, doc.getDocumentElement());
2786:                        Reply ok = createDAVReply(request, HTTP.OK, doc);
2787:                        return ok;
2788:                    }
2789:                    // bad request
2790:                    Reply error = request.makeReply(HTTP.BAD_REQUEST);
2791:                    error.setContent("Invalid request: missing lockinfo");
2792:                    throw new HTTPException(error);
2793:                }
2794:            }
2795:
2796:            /**
2797:             * Handle the UNLOCK request.
2798:             * @param request the WEBDAV request
2799:             * @return a Reply instance
2800:             * @exception ProtocolException If processsing the request failed.
2801:             * @exception ResourceException If the resource got a fatal error.
2802:             */
2803:            public synchronized Reply unlock(DAVRequest request)
2804:                    throws ProtocolException, ResourceException {
2805:                if (debug) {
2806:                    System.out.println(">>> UNLOCK");
2807:                }
2808:                if (!isLocked(request)) {
2809:                    // stupid client :)
2810:                    return request.makeReply(HTTP.NO_CONTENT);
2811:                }
2812:                // check the locktocken header
2813:                String token = request.getLockToken();
2814:                if (token != null) {
2815:                    String mytoken = getCurrentLockToken(request);
2816:                    String rtoken = decodeURL(request, token);
2817:                    if (debug) {
2818:                        System.out.println("REQ  TOKEN : [" + rtoken + "]");
2819:                        System.out.println("LOCK TOKEN : [" + mytoken + "]");
2820:                    }
2821:                    if (rtoken.equals(mytoken) && checkLockOwner(request)) {
2822:                        if (definesAttribute(ATTR_LOCK_TOKEN)) {
2823:                            unlock();
2824:                        } else {
2825:                            ResourceReference rr = (ResourceReference) request
2826:                                    .getState(LOCKED_REREFENCE);
2827:                            if (rr == null) {
2828:                                Reply error = request
2829:                                        .makeReply(HTTP.INTERNAL_SERVER_ERROR);
2830:                                error
2831:                                        .setContent("Unable to unlock, no request state");
2832:                                throw new HTTPException(error);
2833:                            } else {
2834:                                try {
2835:                                    DAVFrame fr = (DAVFrame) rr.lock();
2836:                                    fr.unlock();
2837:                                } catch (Exception ex) {
2838:                                    ex.printStackTrace();
2839:                                    Reply error = request
2840:                                            .makeReply(HTTP.INTERNAL_SERVER_ERROR);
2841:                                    error.setContent(ex.getMessage());
2842:                                    throw new HTTPException(error);
2843:                                } finally {
2844:                                    rr.unlock();
2845:                                }
2846:                            }
2847:                        }
2848:                        return request.makeReply(HTTP.NO_CONTENT);
2849:                    } else {
2850:                        Reply reply = request.makeReply(WEBDAV.LOCKED);
2851:                        reply.setContent("The resource is locked");
2852:                        return reply;
2853:                    }
2854:                }
2855:                // sorry
2856:                Reply error = request.makeReply(HTTP.FORBIDDEN);
2857:                error.setContent("You are not allowed to unlock this resource");
2858:                throw new HTTPException(error);
2859:            }
2860:
2861:            private void updateStates(DAVRequest request) {
2862:                if (getCurrentLockDepth() == WEBDAV.DEPTH_INFINITY) {
2863:                    // propagate the lock
2864:                    request.setState(LOCKED_REREFENCE, getResourceReference());
2865:                    request.setState(LOCK_OWNER, getCurrentLockOwner(null));
2866:                    request.setState(LOCK_TOKEN, getCurrentLockToken(null));
2867:                    request.setState(LOCK_USERNAME,
2868:                            getCurrentLockUsername(null));
2869:                    request.setState(LOCK_EXPIRE, new Long(
2870:                            getTokenExpirationDate(null)));
2871:                    request.setState(LOCK_TIMEOUT, getValue(ATTR_LOCK_TIMEOUT,
2872:                            DEFAULT_LOCK_TIMEOUT));
2873:                }
2874:            }
2875:
2876:            /**
2877:             * Lookup the target resource (dispath to more specific lookup methods).
2878:             * @param ls The current lookup state
2879:             * @param lr The result
2880:             * @return true if lookup is done.
2881:             * @exception ProtocolException If an error relative to the protocol occurs
2882:             * @see #lookupDirectory
2883:             * @see #lookupFile
2884:             * @see #lookupOther
2885:             */
2886:            protected boolean lookupResource(LookupState ls, LookupResult lr)
2887:                    throws ProtocolException {
2888:                DAVRequest request = (DAVRequest) ls.getRequest();
2889:                if ((request != null) && (isLocked(null))) {
2890:                    updateLockDate(request);
2891:                }
2892:                return super .lookupResource(ls, lr);
2893:            }
2894:
2895:            /**
2896:             * Lookup the target resource when associated with a DirectoryResource.
2897:             * @param ls The current lookup state
2898:             * @param lr The result
2899:             * @return true if lookup is done.
2900:             * @exception ProtocolException If an error relative to the protocol
2901:             * occurs
2902:             */
2903:            protected boolean lookupDirectory(LookupState ls, LookupResult lr)
2904:                    throws ProtocolException {
2905:                // handle PUT and MKCOL
2906:                // refresh the timeout value
2907:                DAVRequest request = (DAVRequest) ls.getRequest();
2908:                if (request == null) {
2909:                    return super .lookupDirectory(ls, lr);
2910:                }
2911:                if (isLocked(null)) {
2912:                    updateStates(request);
2913:                }
2914:                if (ls.hasMoreComponents()) {
2915:                    if (request.getMethod().equals("PUT")) {
2916:                        String name = ls.peekNextComponent();
2917:                        ResourceReference rr = dresource.lookup(name);
2918:                        if ((rr == null) && dresource.getExtensibleFlag()
2919:                                && getPutableFlag()) {
2920:                            // the resource doesn't exists
2921:                            if (ls.countRemainingComponents() == 1) {
2922:                                rr = dresource.createResource(name, request);
2923:                                if (rr == null) {
2924:                                    Reply error = request
2925:                                            .makeReply(HTTP.UNSUPPORTED_MEDIA_TYPE);
2926:                                    error
2927:                                            .setContent("Failed to create resource "
2928:                                                    + name
2929:                                                    + " : "
2930:                                                    + "Unable to create the appropriate file:"
2931:                                                    + request.getURLPath()
2932:                                                    + " this media type is not supported");
2933:                                    throw new HTTPException(error);
2934:                                }
2935:                            } else { //FORBIDDEN IN WEBDAV
2936:                                Reply error = request.makeReply(HTTP.CONFLICT);
2937:                                error.setContent(name + " does not exists!");
2938:                                throw new HTTPException(error);
2939:                            }
2940:                        } else if (rr == null) {
2941:                            Reply error = request.makeReply(HTTP.FORBIDDEN);
2942:                            error
2943:                                    .setContent("You are not allowed to create resource "
2944:                                            + name
2945:                                            + " : "
2946:                                            + dresource.getIdentifier()
2947:                                            + " is not extensible.");
2948:                            throw new HTTPException(error);
2949:                        }
2950:                    } else if (request.getMethod().equals("MKCOL")) {
2951:                        String name = ls.peekNextComponent();
2952:                        ResourceReference rr = dresource.lookup(name);
2953:                        if (rr == null) {
2954:                            if (ls.countRemainingComponents() == 1) {
2955:                                request.setState(REMAINING_PATH, name);
2956:                                return true;
2957:                            } else {
2958:                                Reply error = request.makeReply(HTTP.CONFLICT);
2959:                                error.setContent("Can't create "
2960:                                        + ls.getRemainingPath(true));
2961:                                throw new HTTPException(error);
2962:                            }
2963:                        }
2964:                    }
2965:                }
2966:                // normal lookup
2967:                if (super .lookupOther(ls, lr)) {
2968:                    if (!ls.isDirectory() && !ls.isInternal()) {
2969:                        // The directory lookup URL doesn't end with a slash:
2970:                        if (request == null) {
2971:                            lr.setTarget(null);
2972:                            return true;
2973:                        } else if (!acceptRedirect(request)) {
2974:                            return true;
2975:                        }
2976:                        URL url = null;
2977:                        try {
2978:                            if ((request != null)
2979:                                    && request.hasState(Request.ORIG_URL_STATE)) {
2980:                                URL oldurl;
2981:                                oldurl = (URL) request
2982:                                        .getState(Request.ORIG_URL_STATE);
2983:                                url = new URL(oldurl, oldurl.getFile() + "/");
2984:                            } else {
2985:                                url = (ls.hasRequest() ? getURL(request)
2986:                                        : new URL(getServer().getURL(),
2987:                                                resource.getURLPath()));
2988:                            }
2989:                        } catch (MalformedURLException ex) {
2990:                            getServer().errlog(this ,
2991:                                    "unable to build full URL.");
2992:                            throw new HTTPException("Internal server error");
2993:                        }
2994:                        String msg = "Invalid requested URL: the directory resource "
2995:                                + " you are trying to reach is available only through "
2996:                                + " its full URL: <a href=\""
2997:                                + url
2998:                                + "\">"
2999:                                + url + "</a>.";
3000:                        if (getRelocateFlag()) {
3001:                            // Emit an error (with reloc if allowed)
3002:                            Reply reloc = request.makeReply(HTTP.FOUND);
3003:                            reloc.setContent(msg);
3004:                            reloc.setLocation(url);
3005:                            lr.setTarget(null);
3006:                            lr.setReply(reloc);
3007:                            return true;
3008:                        } else {
3009:                            Reply error = request.makeReply(HTTP.NOT_FOUND);
3010:                            error.setContent(msg);
3011:                            lr.setTarget(null);
3012:                            lr.setReply(error);
3013:                            return true;
3014:                        }
3015:                    } else if (!ls.isInternal() && acceptRedirect(request)) {
3016:                        request.setState(STATE_CONTENT_LOCATION, "true");
3017:                        // return the index file.
3018:                        String indexes[] = getIndexes();
3019:                        if (indexes != null) {
3020:                            for (int i = 0; i < indexes.length; i++) {
3021:                                String index = indexes[i];
3022:                                if (index != null && index.length() > 0) {
3023:                                    DirectoryResource dir = (DirectoryResource) resource;
3024:                                    ResourceReference rr = dir.lookup(index);
3025:                                    if (rr != null) {
3026:                                        try {
3027:                                            FramedResource rindex = (FramedResource) rr
3028:                                                    .lock();
3029:                                            return rindex.lookup(ls, lr);
3030:                                        } catch (InvalidResourceException ex) {
3031:                                        } finally {
3032:                                            rr.unlock();
3033:                                        }
3034:                                    }
3035:                                }
3036:                            }
3037:                        }
3038:                    }
3039:                    return true;
3040:                }
3041:                return false;
3042:            }
3043:
3044:            /**
3045:             * companion to initialize, called after the register
3046:             */
3047:            public void registerResource(FramedResource resource) {
3048:                super .registerResource(resource);
3049:                ObservableProperties props = getResource().getServer()
3050:                        .getProperties();
3051:                manager = org.w3c.www.protocol.webdav.DAVManager
3052:                        .getDAVManager(props);
3053:            }
3054:
3055:            public void initialize(Object values[]) {
3056:                super .initialize(values);
3057:                if (getCreationDate() == -1) { // first time 
3058:                    setValue(ATTR_CREATION_DATE, new Long(System
3059:                            .currentTimeMillis()));
3060:                }
3061:            }
3062:
3063:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.