Source Code Cross Referenced for ResourceImpl.java in  » Content-Management-System » harmonise » com » ibm » webdav » impl » 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 » Content Management System » harmonise » com.ibm.webdav.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * (C) Copyright IBM Corp. 2000  All rights reserved.
0003:         *
0004:         * The program is provided "AS IS" without any warranty express or
0005:         * implied, including the warranty of non-infringement and the implied
0006:         * warranties of merchantibility and fitness for a particular purpose.
0007:         * IBM will not be liable for any damages suffered by you as a result
0008:         * of using the Program. In no event will IBM be liable for any
0009:         * special, indirect or consequential damages or lost profits even if
0010:         * IBM has been advised of the possibility of their occurrence. IBM
0011:         * will not be liable for any third party claims against you.
0012:         * 
0013:         * Portions Copyright (C) Simulacra Media Ltd, 2004.
0014:         */
0015:
0016:        package com.ibm.webdav.impl;
0017:
0018:        //import java.net.URLConnection;
0019:        import java.io.*;
0020:        import java.net.*;
0021:        import java.rmi.*;
0022:        import java.rmi.server.*;
0023:        import java.util.*;
0024:
0025:        import javax.xml.parsers.*;
0026:
0027:        import org.w3c.dom.*;
0028:
0029:        import com.ibm.webdav.*;
0030:        import com.ibm.webdav.Collection;
0031:        import com.ibm.webdav.protocol.http.*;
0032:
0033:        /** Implements the Resource interface and all the WebDAV semantics. ResourceImpl
0034:         * delegates certain low-level repository operations to managers provided for a
0035:         * particular repository implementation. There are three repository managers
0036:         * factoring the repository-specific behavior: NamesapceManager, PropertiesManager,
0037:         * and LockManager. ResourceImplFactory constructs the appropriate managers for
0038:         * this resource based on its URL. Mapping information from URL to repository
0039:         * manager is configured in the dav4j.properties file.
0040:         * <p>
0041:         * ResourceImpl is generally used by a server to implement the WebDAV protocol.
0042:         * However, it may also be used directly on the client if the resource URL is the localhost
0043:         * and in that case, there are no remote procedure calls, and no need for a
0044:         * server to run.
0045:         * @author Jim Amsden &lt;jamsden@us.ibm.com&gt;
0046:         * @see ResourceImplCollection
0047:         * @see ResourceHTTPSkel
0048:         */
0049:        public class ResourceImpl implements  IRResource {
0050:            /** Setting debug to true causes debug information to be printed to System.err for
0051:             * each method. This value can be changed by setting its value in
0052:             * the dav4j.properties file and restarting the server.
0053:             */
0054:            public static boolean debug = false;
0055:            public static java.util.Properties webdavProperties = new java.util.Properties();
0056:            // properties taken from dav4j.properties.
0057:            private static Vector liveProperties = new Vector();
0058:            // the generic live properties
0059:
0060:            static {
0061:                // Find the dav4j.properties file in the classpath
0062:                String classpath = System.getProperty("java.class.path");
0063:                StringTokenizer paths = new StringTokenizer(classpath, ";");
0064:                File propertiesFile = null;
0065:                boolean found = false;
0066:
0067:                while (!found && paths.hasMoreTokens()) {
0068:                    String path = paths.nextToken();
0069:                    propertiesFile = new File(path, "dav4j.properties");
0070:                    found = propertiesFile.exists();
0071:                }
0072:
0073:                if (found) {
0074:                    try {
0075:                        webdavProperties.load(new FileInputStream(
0076:                                propertiesFile));
0077:                    } catch (Exception exc) {
0078:                        exc.printStackTrace();
0079:                    }
0080:                }
0081:
0082:                String debugString = webdavProperties.getProperty("debug");
0083:                debug = (debugString != null) && debugString.equals("true");
0084:
0085:                // create the live properties
0086:                liveProperties.addElement(new LockDiscovery());
0087:            }
0088:
0089:            // contexts for communicating HTTP and WebDAV headers (method contol couples)
0090:            protected ResourceContext context = new ResourceContext();
0091:
0092:            //------------------------------------------------------------------------------------
0093:            protected String fileName = null;
0094:            protected URL url = null;
0095:            protected NamespaceManager namespaceManager = null;
0096:            protected PropertiesManager propertiesManager = null;
0097:            protected LockManager lockManager = null;
0098:            static protected SearchManager searchManager = null;
0099:            static protected UserAuthenticator authenticator = null;
0100:
0101:            public ResourceImpl() {
0102:                this .url = null;
0103:                this .fileName = null;
0104:            }
0105:
0106:            /** Construct a ResourceImpl for the given URL.
0107:             *
0108:             * @param url the URL of the resource
0109:             * @param localName a translation of the URL (filePortion) into
0110:             * a name that has local meaning to a server.
0111:             * @exception com.ibm.webdav.WebDAVException
0112:             */
0113:            public ResourceImpl(URL url, String localName)
0114:                    throws WebDAVException {
0115:                this .url = url;
0116:                this .fileName = localName;
0117:
0118:                if (url.getProtocol().equals("rmi")) {
0119:                    try {
0120:                        UnicastRemoteObject.exportObject(this );
0121:                    } catch (java.rmi.RemoteException exc) {
0122:                        throw new WebDAVException(
0123:                                WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
0124:                                "Unable to export rmi object");
0125:                    }
0126:                }
0127:
0128:                // TODO: get the Namespace to use from the dav4j.properties file
0129:                // need to use a factory to do this
0130:                namespaceManager = ResourceImplFactory
0131:                        .createNamespaceManager(this );
0132:                propertiesManager = ResourceImplFactory
0133:                        .createPropertiesManager(this , namespaceManager);
0134:                lockManager = ResourceImplFactory.createLockManager(this ,
0135:                        namespaceManager, propertiesManager);
0136:
0137:                if (searchManager == null) {
0138:                    searchManager = ResourceImplFactory
0139:                            .createSearchManager(this );
0140:                }
0141:
0142:                if (authenticator == null) {
0143:                    authenticator = ResourceImplFactory.getAuthenticator(this );
0144:                }
0145:
0146:                // Set some default response context
0147:                // Don't let proxy servers cache contents or properties
0148:                getResponseContext().put("Cache-Control", "No-Cache");
0149:                getResponseContext().put("Pragma", "No-Cache");
0150:
0151:                // identify ourselves
0152:                getResponseContext().put("Server", "IBM DAV4J Server/1.0");
0153:            }
0154:
0155:            /** Construct a ResourceImpl for the given URL.
0156:             *
0157:             * @param url the URL of the resource
0158:             * @param localName a translation of the URL (filePortion) into
0159:             * a name that has local meaning to a server.
0160:             * @param targetSelector the revision target selector for this Collection
0161:             * @exception com.ibm.webdav.WebDAVException
0162:             */
0163:            public ResourceImpl(URL url, String localName,
0164:                    TargetSelector targetSelector) throws WebDAVException {
0165:                this .url = url;
0166:                this .fileName = localName;
0167:
0168:                if (url.getProtocol().equals("rmi")) {
0169:                    try {
0170:                        UnicastRemoteObject.exportObject(this );
0171:                    } catch (java.rmi.RemoteException exc) {
0172:                        throw new WebDAVException(
0173:                                WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
0174:                                "Unable to export rmi object");
0175:                    }
0176:                }
0177:
0178:                // TODO: get the Namespace to use from the dav4j.properties file
0179:                // need to use a factory to do this
0180:                namespaceManager = ResourceImplFactory
0181:                        .createNamespaceManager(this );
0182:                propertiesManager = ResourceImplFactory
0183:                        .createPropertiesManager(this , namespaceManager);
0184:                lockManager = ResourceImplFactory.createLockManager(this ,
0185:                        namespaceManager, propertiesManager);
0186:                if (searchManager == null) {
0187:                    searchManager = ResourceImplFactory
0188:                            .createSearchManager(this );
0189:                }
0190:
0191:                if (authenticator == null) {
0192:                    authenticator = ResourceImplFactory.getAuthenticator(this );
0193:                }
0194:
0195:                // Set some default response context
0196:                // Don't let proxy servers cache contents or properties
0197:                getResponseContext().put("Cache-Control", "No-Cache");
0198:                getResponseContext().put("Pragma", "No-Cache");
0199:
0200:                // identify ourselves
0201:                getResponseContext().put("Server", "IBM DAV4J Server/1.0");
0202:            }
0203:
0204:            /** This method must be called after the client has completed writing to the contents
0205:             * output stream that was obtained from <code>getContentsOutputStream()</code>.
0206:             * @exception com.ibm.webdav.WebDAVException
0207:             */
0208:            public void closeContentsOutputStream(ResourceContext context)
0209:                    throws WebDAVException {
0210:                closeContentsOutputStream(context, null);
0211:            }
0212:
0213:            /** Copy this resource to the destination URL.
0214:             * Partial results are possible, check the returned status for details.
0215:             *
0216:             * @param destinationURL the destination
0217:             * @param overwrite true implies overrite the destination if it exists
0218:             * @param propertiesToCopy a collection of properties that must be copied or
0219:             * the method will fail. propertiesToCopy may have one of the following values:
0220:             * <ul>
0221:             *    <li>null - ignore properties that cannot be copied</li>
0222:             *    <li>empty collection - all properties must be copied or the method will fail</li>
0223:             *    <li>a collection of URIs - a list of the properties that must be copied
0224:             *        or the method will fail</li>
0225:             * </ul>
0226:             *
0227:             * @return the status of the copy operation for each resource copied
0228:             * @exception com.ibm.webdav.WebDAVException
0229:             */
0230:            public MultiStatus atomicMove(ResourceContext context,
0231:                    String destinationURL, boolean overwrite)
0232:                    throws WebDAVException {
0233:                this .context = context;
0234:
0235:                setStatusCode(WebDAVStatus.SC_CREATED);
0236:
0237:                // create a MultiStatus to hold the results
0238:                MultiStatus multiStatus = new MultiStatus();
0239:
0240:                try {
0241:                    // validate the uri
0242:                    if (!hasValidURI()) {
0243:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0244:                                "Invalid URI");
0245:                    }
0246:
0247:                    // make sure the resource exists
0248:                    if (!exists()) {
0249:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
0250:                                "Cannot copy a lock-null resource");
0251:                    }
0252:
0253:                    // the destination may be a relative URL
0254:                    URL destURL = new URL(this .url, destinationURL);
0255:                    Resource destination = new Resource(destURL.toString());
0256:
0257:                    // are the source and destination the same?
0258:                    if (this .equals(destination)) {
0259:                        throw new WebDAVException(WebDAVStatus.SC_FORBIDDEN,
0260:                                "Can't copy source on top of itself");
0261:                    }
0262:
0263:                    // is the destination locked?
0264:                    destination.getRequestContext().precondition(
0265:                            getRequestContext().precondition());
0266:                    destination.getRequestContext().authorization(
0267:                            getRequestContext().authorization());
0268:
0269:                    if (destination.exists()) {
0270:                        if (destination.isLocked()) {
0271:                            if (!destination.isLockedByMe()) {
0272:                                throw new WebDAVException(
0273:                                        WebDAVStatus.SC_LOCKED,
0274:                                        "Destination resource is locked");
0275:                            }
0276:                        }
0277:                    }
0278:
0279:                    // check to see if the destination exists and its OK to overwrite it
0280:                    if (destination.exists()) {
0281:                        if (!overwrite) {
0282:                            throw new WebDAVException(
0283:                                    WebDAVStatus.SC_PRECONDITION_FAILED,
0284:                                    "Destination exists and overwrite not specified");
0285:                        } else {
0286:                            setStatusCode(WebDAVStatus.SC_NO_CONTENT);
0287:                        }
0288:                    }
0289:
0290:                    this .namespaceManager.move(URLDecoder
0291:                            .decode(ResourceFactory.getRealPath(destURL)));
0292:
0293:                    // everything must have gone OK, there
0294:                    // is no response for a successful delete
0295:                    getResponseContext().contentType("text/xml");
0296:                } catch (WebDAVException exc) {
0297:                    throw exc;
0298:                } catch (java.net.MalformedURLException exc) {
0299:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0300:                            "Malformed URL");
0301:                } catch (java.io.IOException exc) {
0302:                    throw new WebDAVException(
0303:                            WebDAVStatus.SC_INTERNAL_SERVER_ERROR, "IO Error");
0304:                }
0305:
0306:                return multiStatus;
0307:            }
0308:
0309:            /** Copy this resource to the destination URL.
0310:             * Partial results are possible, check the returned status for details.
0311:             *
0312:             * @param destinationURL the destination
0313:             * @param overwrite true implies overrite the destination if it exists
0314:             * @param propertiesToCopy a collection of properties that must be copied or
0315:             * the method will fail. propertiesToCopy may have one of the following values:
0316:             * <ul>
0317:             *    <li>null - ignore properties that cannot be copied</li>
0318:             *    <li>empty collection - all properties must be copied or the method will fail</li>
0319:             *    <li>a collection of URIs - a list of the properties that must be copied
0320:             *        or the method will fail</li>
0321:             * </ul>
0322:             *
0323:             * @return the status of the copy operation for each resource copied
0324:             * @exception com.ibm.webdav.WebDAVException
0325:             */
0326:            public MultiStatus copy(ResourceContext context,
0327:                    String destinationURL, boolean overwrite,
0328:                    Vector propertiesToCopy) throws WebDAVException {
0329:                this .context = context;
0330:
0331:                setStatusCode(WebDAVStatus.SC_CREATED);
0332:
0333:                // create a MultiStatus to hold the results
0334:                MultiStatus multiStatus = new MultiStatus();
0335:
0336:                try {
0337:                    // validate the uri
0338:                    if (!hasValidURI()) {
0339:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0340:                                "Invalid URI");
0341:                    }
0342:
0343:                    // make sure the resource exists
0344:                    if (!exists()) {
0345:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
0346:                                "Cannot copy a lock-null resource");
0347:                    }
0348:
0349:                    // the destination may be a relative URL
0350:                    URL destURL = new URL(this .url, destinationURL);
0351:                    Resource destination = new Resource(destURL.toString());
0352:
0353:                    String sContentType = namespaceManager.getContentType();
0354:
0355:                    // are the source and destination the same?
0356:                    if (this .equals(destination)) {
0357:                        throw new WebDAVException(WebDAVStatus.SC_FORBIDDEN,
0358:                                "Can't copy source on top of itself");
0359:                    }
0360:
0361:                    // is the destination locked?
0362:                    destination.getRequestContext().precondition(
0363:                            getRequestContext().precondition());
0364:                    destination.getRequestContext().authorization(
0365:                            getRequestContext().authorization());
0366:
0367:                    if (destination.exists()) {
0368:                        if (destination.isLocked()) {
0369:                            if (!destination.isLockedByMe()) {
0370:                                throw new WebDAVException(
0371:                                        WebDAVStatus.SC_LOCKED,
0372:                                        "Destination resource is locked");
0373:                            }
0374:                        }
0375:                    }
0376:
0377:                    // check to see if the destination exists and its OK to overwrite it
0378:                    if (destination.exists()) {
0379:                        if (!overwrite) {
0380:                            throw new WebDAVException(
0381:                                    WebDAVStatus.SC_PRECONDITION_FAILED,
0382:                                    "Destination exists and overwrite not specified");
0383:                        } else {
0384:                            setStatusCode(WebDAVStatus.SC_NO_CONTENT);
0385:                        }
0386:                    }
0387:
0388:                    InputStream is = getContentsInputStream(context);
0389:
0390:                    OutputStream os = destination.getContentsOutputStream();
0391:                    if (is != null) {
0392:                        byte[] buf = new byte[8192];
0393:                        int numRead = 0;
0394:
0395:                        while ((numRead = is.read(buf, 0, buf.length)) != -1) {
0396:                            os.write(buf, 0, numRead);
0397:                        }
0398:                        is.close();
0399:                    }
0400:
0401:                    destination.closeContentsOutputStream(sContentType);
0402:
0403:                    // copy the properties
0404:                    WebDAVStatus savedStatusCode = getStatusCode();
0405:                    MultiStatus ms2 = copyProperties(destination,
0406:                            propertiesToCopy);
0407:
0408:                    if (!ms2.isOK()) {
0409:                        // todo: add code here to back out this partial copy. That might require
0410:                        //    restoring the resource that used to be at the destination. For now, we'll throw
0411:                        //    an exception.
0412:                        throw new WebDAVException(
0413:                                WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
0414:                                "problem copying properties");
0415:                    }
0416:
0417:                    setStatusCode(savedStatusCode);
0418:
0419:                    // remove all locks on the destination. Copy doesn't copy locks
0420:                    // become super-user for this operation
0421:                    String authorization = getRequestContext().authorization();
0422:                    destination.getRequestContext().setBasicAuthorization(
0423:                            "root", "");
0424:
0425:                    Enumeration locks = destination.getLocks().elements();
0426:
0427:                    while (locks.hasMoreElements()) {
0428:                        ActiveLock lock = (ActiveLock) locks.nextElement();
0429:
0430:                        // ignore exceptions, the unlock should work
0431:                        try {
0432:                            destination.unlock(lock.getLockToken());
0433:                        } catch (Exception exc) {
0434:                        }
0435:                    }
0436:
0437:                    destination.getRequestContext()
0438:                            .authorization(authorization);
0439:
0440:                    // everything must have gone OK, there
0441:                    // is no response for a successful delete
0442:                    getResponseContext().contentType("text/xml");
0443:                } catch (WebDAVException exc) {
0444:                    throw exc;
0445:                } catch (java.net.MalformedURLException exc) {
0446:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0447:                            "Malformed URL");
0448:                } catch (java.io.IOException exc) {
0449:                    throw new WebDAVException(
0450:                            WebDAVStatus.SC_INTERNAL_SERVER_ERROR, "IO Error");
0451:                }
0452:
0453:                return multiStatus;
0454:            }
0455:
0456:            /** Copy the properties of this resource to the destination resource.
0457:             * Follow any keepalive instructions in the propertiesToCopy vector.
0458:             * @param destination the destination resource
0459:             * @param propertiesToCopy properties that must be kept alive at the destination
0460:             * <ul>
0461:             *    <li>null - ignore properties that cannot be copied</li>
0462:             *    <li>empty collection - all properties must be copied or the method will fail</li>
0463:             *    <li>a collection of URIs - a list of the properties that must be copied
0464:             *        or the method will fail</li>
0465:             * </ul>
0466:             * @return a MultiStatus indicating the result of the copy operation
0467:             * @exception com.ibm.webdav.WebDAVException
0468:             */
0469:            protected MultiStatus copyProperties(Resource destination,
0470:                    Vector propertiesToCopy) throws WebDAVException {
0471:                MultiStatus result = getProperties(context);
0472:                boolean bOnlySomeProperties = ((propertiesToCopy != null) && (propertiesToCopy
0473:                        .size() > 0));
0474:
0475:                // create a property update document
0476:                Document document = null;
0477:
0478:                try {
0479:                    DocumentBuilderFactory factory = DocumentBuilderFactory
0480:                            .newInstance();
0481:                    factory.setNamespaceAware(true);
0482:
0483:                    DocumentBuilder docbuilder = factory.newDocumentBuilder();
0484:                    document = docbuilder.newDocument();
0485:                } catch (Exception e) {
0486:                    throw new WebDAVException(
0487:                            WebDAVStatus.SC_INTERNAL_SERVER_ERROR, e
0488:                                    .getMessage());
0489:                }
0490:
0491:                //document.setVersion(Resource.XMLVersion);
0492:                //document.setEncoding(Resource.defaultXMLEncoding);
0493:                Element propertyUpdate = document.createElementNS("DAV:",
0494:                        "D:propertyupdate");
0495:
0496:                propertyUpdate.setAttribute("xmlns:D", "DAV:");
0497:                document.appendChild(propertyUpdate);
0498:
0499:                Element set = document.createElementNS("DAV:", "D:set");
0500:
0501:                propertyUpdate.appendChild(set);
0502:
0503:                Element prop = document.createElementNS("DAV:", "D:prop");
0504:
0505:                set.appendChild(prop);
0506:
0507:                Hashtable PropsWillCopy = new java.util.Hashtable();
0508:
0509:                // fill in the properties from the source
0510:                PropertyResponse response = (PropertyResponse) result
0511:                        .getResponses().nextElement();
0512:                Enumeration propertyNames = response.getPropertyNamesPN();
0513:
0514:                while (propertyNames.hasMoreElements()) {
0515:                    PropertyName name = (PropertyName) propertyNames
0516:                            .nextElement();
0517:                    PropertyValue value = response.getProperty(name);
0518:                    Node node = document.importNode(value.value, true);
0519:                    PropsWillCopy.put(name, node);
0520:                    prop.appendChild((Element) node);
0521:                }
0522:
0523:                // attempt to update all the properties at the destination
0524:                MultiStatus msRc = destination.setProperties(document);
0525:
0526:                // now look at what happened, and adjust based on the propertiesToCopy
0527:                Enumeration resources = msRc.getResponses();
0528:
0529:                while (resources.hasMoreElements()) {
0530:                    Response resmember = (Response) resources.nextElement();
0531:                    PropertyResponse propresponse = resmember
0532:                            .toPropertyResponse();
0533:                    Dictionary htProperties = (Hashtable) propresponse
0534:                            .getPropertiesByPropName();
0535:                    Enumeration propertynames = htProperties.keys();
0536:
0537:                    while (propertynames.hasMoreElements()) {
0538:                        PropertyName propname = (PropertyName) propertynames
0539:                                .nextElement();
0540:                        PropertyValue pv = (PropertyValue) htProperties
0541:                                .get(propname);
0542:                        int stat = pv.getStatus();
0543:
0544:                        if ((stat != WebDAVStatus.SC_OK)
0545:                                && (stat != WebDAVStatus.SC_FAILED_DEPENDENCY)) {
0546:                            Node node = (Node) PropsWillCopy.get(propname);
0547:
0548:                            if ((propertiesToCopy == null)
0549:                                    || (propertiesToCopy.size() > 0 && !propertiesToCopy
0550:                                            .contains(propname))) {
0551:                                prop.removeChild(node); // don't need to copy this one
0552:                            }
0553:                        }
0554:                    }
0555:                }
0556:
0557:                // attempt to update the remaining properties again
0558:                // after removing the ones that can be allowed to fail.
0559:                // This has to be a two step process because there's no
0560:                // way to determine what properties are live on anoter
0561:                // server. We're trying to get a propertyupdate element
0562:                // on PROPPATCH too so this extra step can be avoided.
0563:                return destination.setProperties(document);
0564:            }
0565:
0566:            /** Create a instance of a ResourceImpl with the given URL and localName.
0567:             *
0568:             * @param url the URL of the resource to create
0569:             * @param localName the name of the resource on the server machine
0570:             * @return a ResourceImpl or one of its subclasses.
0571:             * @exception com.ibm.webdav.WebDAVException
0572:             */
0573:            public static ResourceImpl create(URL url, String localName)
0574:                    throws WebDAVException {
0575:                ResourceImpl resource = new ResourceImpl(url, localName);
0576:
0577:                if (resource.isCollection()) {
0578:                    resource = new CollectionImpl(url, localName, null);
0579:                }
0580:
0581:                return resource;
0582:            }
0583:
0584:            /** Build a multistatus property response that returns the error specified
0585:            by the given exception.  It should return this error for every property provided
0586:            in the specified document which should represent the XML of a PROPPATCH
0587:            request.
0588:             *
0589:             * @param exc an exception that describes the error to be placed in the MultiStatus created.
0590:             * @param updates an XML Document containing DAV:propertyupdate elements
0591:             * describing the edits that were request orginally requested and
0592:             * apparently generated the given exception.
0593:             * @return a MultiStatus indicating the status of the updates
0594:             * @exception com.ibm.webdav.WebDAVException
0595:             */
0596:            public MultiStatus createPropPatchMultiStatus(WebDAVException exc,
0597:                    Document updates) throws WebDAVException {
0598:                MultiStatus ms2 = new MultiStatus();
0599:                Element el0 = updates.getDocumentElement();
0600:                Element txel0 = (Element) el0;
0601:                NodeList nl = txel0.getElementsByTagNameNS("DAV:", "prop");
0602:
0603:                /*Element na[] = txel0.searchDescendantsAll(  Match.NSLOCAL, //Match.QNAME,
0604:                "DAV:", "prop" );*/
0605:                int nllen = nl.getLength();
0606:                int idx = 0;
0607:                String lxx = "xx";
0608:
0609:                if (nllen <= 0) {
0610:                    throw exc;
0611:                }
0612:
0613:                while (idx < nllen) {
0614:                    Element txelProp = (Element) nl.item(idx);
0615:                    Node node2 = txelProp.getFirstChild();
0616:                    Element txel2 = null;
0617:
0618:                    try {
0619:                        txel2 = (Element) node2;
0620:                    } catch (Exception exc2) {
0621:                        throw exc;
0622:                    }
0623:
0624:                    {
0625:                        // todo: add code to handle the responsedescription in the exception and
0626:                        //     include it in the multistatus response.
0627:                        PropertyName pn = new PropertyName(txel2);
0628:                        PropertyResponse response = new PropertyResponse(
0629:                                getURL().toString());
0630:                        response.addProperty(pn, (Element) txel2
0631:                                .cloneNode(false), exc.getStatusCode());
0632:                        ms2.addResponse(response);
0633:                    }
0634:
0635:                    idx++;
0636:                }
0637:
0638:                return ms2;
0639:            }
0640:
0641:            /** Delete this resouce from the server. The actual effect of the delete operation is
0642:             * determined by the underlying repository manager. The visible effect to WebDAV
0643:             * is that the resource is no longer available.
0644:             *
0645:             * @return a MultiStatus containing the status of the delete method on each
0646:             *         effected resource.
0647:             * @exception com.ibm.webdav.WebDAVException
0648:             */
0649:            public MultiStatus delete(ResourceContext context)
0650:                    throws WebDAVException {
0651:                this .context = context;
0652:
0653:                setStatusCode(WebDAVStatus.SC_NO_CONTENT);
0654:
0655:                MultiStatus result = new MultiStatus();
0656:
0657:                // validate the uri
0658:                if (!hasValidURI()) {
0659:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0660:                            "Invalid URI");
0661:                }
0662:
0663:                // make sure the parent collection exists
0664:                CollectionImpl parent = (CollectionImpl) getParentCollection();
0665:
0666:                if ((parent != null) && !parent.exists()) {
0667:                    throw new WebDAVException(WebDAVStatus.SC_CONFLICT,
0668:                            "Parent collection does not exist");
0669:                }
0670:
0671:                // TODO support shared locks here or wherever needs it
0672:                /*
0673:                 * 
0674:                
0675:                 QUICK FIX
0676:                
0677:                 Commenting this out to allow addition of members to locked collections
0678:                
0679:                 Will have to implement the shared lock thing eventually to support this
0680:                
0681:
0682:                // make sure the parent collection is not locked, or is locked by this user
0683:                if (parent != null) {
0684:                parent.getRequestContext().precondition(
0685:                	getRequestContext().precondition());
0686:                parent.getRequestContext().authorization(
0687:                	getRequestContext().authorization());
0688:
0689:                if (parent.isLocked() && !parent.isLockedByMe()) {
0690:                	throw new WebDAVException(
0691:                		WebDAVStatus.SC_LOCKED,
0692:                		"Parent collection is locked by another user");
0693:                }
0694:                }
0695:                 */
0696:
0697:                if (!exists()) {
0698:                    throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
0699:                            "Resource does not exist");
0700:                }
0701:
0702:                // check to see if the resource is locked by another user
0703:                if (isLocked() && !isLockedByMe()) {
0704:                    throw new WebDAVException(WebDAVStatus.SC_LOCKED,
0705:                            "Resource is locked by another user");
0706:                }
0707:
0708:                // reset statusCode because isLocked has a side effect of changing it
0709:                //    to 207 multistatus.
0710:                setStatusCode(WebDAVStatus.SC_NO_CONTENT);
0711:
0712:                // Attempt to delete this resource
0713:                namespaceManager.delete();
0714:                propertiesManager.deleteProperties();
0715:                getResponseContext().contentType("text/xml");
0716:
0717:                return result;
0718:            }
0719:
0720:            /** Unlock the lock identified by the lockToken on this resource. This method
0721:             * is used internally to unlock resources copied or moved as well as unlocked.
0722:             *
0723:             * @param lockToken the lock token obtained from the ActiveLock of a previous <code>lock() </code>
0724:             *     or <code>getLocks()</code>.
0725:             *
0726:             * @return a MultiStatus containing any responses on resources that could not
0727:             *     be unlocked.
0728:             * @exception com.ibm.webdav.WebDAVException
0729:             */
0730:            protected MultiStatus doUnlock(String lockToken)
0731:                    throws WebDAVException {
0732:                String principal = getRequestContext().getAuthorizationId();
0733:
0734:                // get the locks on this resource
0735:                Enumeration locks = getLocks().elements();
0736:
0737:                // find the lock to unlock
0738:                ActiveLock lockToRemove = null;
0739:
0740:                while (locks.hasMoreElements()) {
0741:                    ActiveLock activeLock = (ActiveLock) locks.nextElement();
0742:
0743:                    if (activeLock.getLockToken().equals(lockToken)
0744:                            && (activeLock.getPrincipal().equals(principal)
0745:                                    || principal.equals("root") || authenticator
0746:                                    .isSuperUser(this ) == true)) {
0747:                        lockToRemove = activeLock;
0748:
0749:                        break;
0750:                    }
0751:                }
0752:
0753:                if (lockToRemove == null) {
0754:                    throw new WebDAVException(
0755:                            WebDAVStatus.SC_PRECONDITION_FAILED,
0756:                            "resource is not locked by this principal");
0757:                }
0758:
0759:                MultiStatus result = lockManager.unlock(lockToRemove);
0760:
0761:                // delete a lock-null resource that has no remaining activelocks
0762:                locks = getLocks().elements();
0763:
0764:                if (!locks.hasMoreElements() && namespaceManager.isLockNull()) {
0765:                    propertiesManager.deleteProperties();
0766:                }
0767:
0768:                getResponseContext().contentType("text/xml");
0769:
0770:                return result;
0771:            }
0772:
0773:            /** See if the contents of this resource exists. A resource exists
0774:             * if it has contents or state maintained by a server.
0775:             *
0776:             * @return true if the contents exists, false otherwise
0777:             * @exception com.ibm.webdav.WebDAVException
0778:             */
0779:            public boolean exists() throws WebDAVException {
0780:                return namespaceManager.exists();
0781:            }
0782:
0783:            public boolean authenticateUser(String user, String pwd)
0784:                    throws WebDAVException {
0785:                boolean bIsAuthenticated = true;
0786:
0787:                if (authenticator != null) {
0788:                    bIsAuthenticated = authenticator.authenticate(user, pwd);
0789:                }
0790:
0791:                return bIsAuthenticated;
0792:            }
0793:
0794:            /** Get the active lock on this resource owned by the given principal if any.
0795:             * NOTE: this method cannot be reliably implemented based on version 10 of
0796:             * the WebDAV spec as an activelock element in a lockdiscovery does not contain
0797:             * the authorization credentials of the owner of the lock. For now, this method
0798:             * relies on an additional principal element in the activelock that contains
0799:             * the required id. This is an IBM EXTENSTION. When WebDAV ACLs are introduced,
0800:             * the principal will likely be added to the activelock element.
0801:             *
0802:             * @param principal the authorization id of the requesting principal
0803:             *
0804:             * @return the active lock owned by that principal or null if the resource is
0805:             * not locked by that principal.
0806:             * @exception com.ibm.webdav.WebDAVException
0807:             */
0808:            protected ActiveLock getActiveLockFor(String scope, String type,
0809:                    int timeout, Element owner) throws WebDAVException {
0810:                String principal = getRequestContext().getAuthorizationId();
0811:
0812:                if (principal == null) {
0813:                    throw new WebDAVException(WebDAVStatus.SC_UNAUTHORIZED,
0814:                            "missing authorization identification");
0815:                }
0816:
0817:                // check all the parameters
0818:                if ((scope == null)
0819:                        || (!scope.equals(ActiveLock.exclusive) && !scope
0820:                                .equals(ActiveLock.shared))) {
0821:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0822:                            "unsupported or missing lock scope: " + scope);
0823:                }
0824:
0825:                if ((type == null) || !type.equals(ActiveLock.writeLock)) {
0826:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0827:                            "unsupported or missing lock type: " + type);
0828:                }
0829:
0830:                // handle locking non-existant resources
0831:                if (!exists()) {
0832:                    namespaceManager.createLockNullResource();
0833:                }
0834:
0835:                // We extend ActiveLock  to include the principal and expiration date
0836:                ActiveLock activeLock = new ActiveLock();
0837:                activeLock.setScope(scope);
0838:                activeLock.setLockType(type);
0839:                activeLock.setDepth(Collection.shallow);
0840:
0841:                if (owner != null) {
0842:                    activeLock.setOwner(owner);
0843:                }
0844:
0845:                if (timeout < 0) {
0846:                    activeLock.setTimeout("Infinite");
0847:                } else {
0848:                    activeLock.setTimeout("Second-" + timeout);
0849:                }
0850:
0851:                String lockToken = "opaquelocktoken:" + new UUID();
0852:                activeLock.setLockToken(lockToken);
0853:                activeLock.setPrincipal(principal);
0854:
0855:                return activeLock;
0856:            }
0857:
0858:            /** Get an InputStream for accessing the contents of this resource. This method may provide
0859:             * more efficient access for resources that have large contents. Clients may want to create
0860:             * a Reader to perform appropriate character conversions on this stream.
0861:             *
0862:             * @return an InputStream on the contents
0863:             * @exception com.ibm.webdav.WebDAVException
0864:             */
0865:            public InputStream getContentsInputStream(ResourceContext context)
0866:                    throws WebDAVException {
0867:                this .context = context;
0868:
0869:                // validate the uri
0870:                if (!hasValidURI()) {
0871:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0872:                            "Invalid URI");
0873:                }
0874:
0875:                InputStream is = namespaceManager.getContentsInputStream();
0876:
0877:                return is;
0878:            }
0879:
0880:            /** Get an OutputStream for setting the contents of this resource. This method may provide
0881:             * more efficient access for resources that have large contents. Remember to call
0882:             * closeContentsOutputStream() when all the data has been written.
0883:             *
0884:             * @return an OutputStream to set the contents
0885:             * @exception com.ibm.webdav.WebDAVException
0886:             */
0887:            public OutputStream getContentsOutputStream(ResourceContext context)
0888:                    throws WebDAVException {
0889:                this .context = context;
0890:
0891:                // validate the uri
0892:                if (!hasValidURI()) {
0893:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
0894:                            "Invalid URI");
0895:                }
0896:
0897:                // make sure the parent collection exists
0898:                CollectionImpl parent = (CollectionImpl) getParentCollection();
0899:
0900:                if ((parent != null) && !parent.exists()) {
0901:                    throw new WebDAVException(WebDAVStatus.SC_CONFLICT,
0902:                            "Parent collection does not exist");
0903:                }
0904:
0905:                //TODO support shared locks here or wherever needs it
0906:                /*
0907:                 * 
0908:                 
0909:                 QUICK FIX
0910:                 
0911:                 Commenting this out to allow addition of members to locked collections
0912:                 
0913:                 Will have to implement the shared lock thing eventually to support this
0914:                 
0915:                 
0916:                // make sure the parent collection is not locked, or is locked by this user
0917:                if (parent != null) {
0918:                	// use this resource's precondition, it should contain the
0919:                	// parent locktoken if needed
0920:                	parent.getRequestContext().precondition(
0921:                		getRequestContext().precondition());
0922:                	parent.getRequestContext().authorization(
0923:                		getRequestContext().authorization());
0924:
0925:                	if (parent.isLocked() && !parent.isLockedByMe()) {
0926:                		throw new WebDAVException(
0927:                			WebDAVStatus.SC_LOCKED,
0928:                			"Parent collection is locked by another user");
0929:                	}
0930:                }*/
0931:
0932:                // check to see if the resource is locked by another user
0933:                if (exists() && isLocked() && !isLockedByMe()) {
0934:                    throw new WebDAVException(WebDAVStatus.SC_LOCKED,
0935:                            "Resource is locked by another user");
0936:                }
0937:
0938:                // Resources that already exist are overwritten
0939:                return namespaceManager.getContentsOutputStream();
0940:            }
0941:
0942:            /**
0943:             * Insert the method's description here.
0944:             * Creation date: (4/14/2000 4:14:55 PM)
0945:             * @return com.ibm.webdav.ResourceContext
0946:             */
0947:            public com.ibm.webdav.ResourceContext getContext() {
0948:                return context;
0949:            }
0950:
0951:            /** Return lock manager for this resource
0952:             */
0953:            public LockManager getLockManager() {
0954:                return lockManager;
0955:            }
0956:
0957:            /**Return authenticator for this resource
0958:             *
0959:             */
0960:            public UserAuthenticator getUserAuthenticator() {
0961:                return ResourceImpl.authenticator;
0962:            }
0963:
0964:            /** Get the locks that exist on this resource.
0965:             *
0966:             * @return a Vector of ActiveLock objects
0967:             * @exception com.ibm.webdav.WebDAVException
0968:             */
0969:            public Vector getLocks() throws WebDAVException {
0970:                return lockManager.getLocks();
0971:            }
0972:
0973:            /** This method can be used for obtaining meta-information about this resource without
0974:             * actually reading the resource contents. This meta-information is maintained by the server
0975:             * in addition to the resource properties.</p>
0976:             * <p>
0977:             * After this call, the resource context has been updated and
0978:             * <code>getStatusCode()</code>, <code>getStatusMessage()</code>, and <code>getResponseContext()</code>
0979:             * as well as all the ResourceContext methods return updated values based on the current
0980:             * state of the resource.</p>
0981:             * <p>This methods corresponds to the HTTP HEAD method.</p>
0982:             * <p>
0983:             * Do a getContentsInputStream() to set the response context,
0984:             * then just don't return the stream.
0985:             * @exception com.ibm.webdav.WebDAVException
0986:             */
0987:            public void getMetaInformation(ResourceContext context)
0988:                    throws WebDAVException {
0989:                this .context = context;
0990:
0991:                InputStream is = getContentsInputStream(context);
0992:
0993:                try {
0994:                    is.close();
0995:                } catch (WebDAVException exc) {
0996:                    throw exc;
0997:                } catch (java.io.IOException exc) {
0998:                }
0999:            }
1000:
1001:            /** Return the local name of the resource. What this name actually is
1002:             * depends on the interpretation of the resource URL by the namespace
1003:             * manager servicing it. Repository implementations are free to translate
1004:             * the URL any way they want for their own purposes. For example, the
1005:             * file system implementation uses the doc.root property to translate
1006:             * the file part of the URL into a full pathname.
1007:             * @return the repository specific name for this resource
1008:             * @exception com.ibm.webdav.WebDAVException
1009:             */
1010:            public String getName() throws WebDAVException {
1011:                if ((fileName == null) && (url != null)) {
1012:                    fileName = ResourceFactory.getRealPath(url);
1013:                }
1014:
1015:                String sDecoded = null;
1016:                try {
1017:                    sDecoded = URLDecoder.decode(fileName, "UTF-8");
1018:                } catch (UnsupportedEncodingException e) {
1019:                    throw new WebDAVException(
1020:                            WebDAVStatus.SC_INTERNAL_SERVER_ERROR, e
1021:                                    .getLocalizedMessage());
1022:                }
1023:
1024:                return sDecoded;
1025:            }
1026:
1027:            /** Get the collection containing this resource.
1028:             *
1029:             * @return the parent collection
1030:             * @exception com.ibm.webdav.WebDAVException
1031:             */
1032:            public IRCollection getParentCollection() throws WebDAVException {
1033:                String parentURL = getURL().toString();
1034:                String parentLocalName = getName();
1035:                int delimiterPosition = 0;
1036:
1037:                if (namespaceManager instanceof  VersionedNamespaceManager) {
1038:                    if (((VersionedNamespaceManager) namespaceManager)
1039:                            .isVersionURL(parentURL) == true) {
1040:                        parentURL = ((VersionedNamespaceManager) namespaceManager)
1041:                                .getResourceURL();
1042:                        try {
1043:                            parentLocalName = ResourceFactory
1044:                                    .getRealPath(new URL(url, parentURL));
1045:                        } catch (MalformedURLException e) {
1046:                            throw new WebDAVException(
1047:                                    WebDAVStatus.SC_INTERNAL_SERVER_ERROR, e
1048:                                            .getLocalizedMessage());
1049:                        }
1050:                    }
1051:                }
1052:
1053:                if (parentURL.endsWith("/")) {
1054:                    delimiterPosition = parentURL.substring(0,
1055:                            parentURL.length() - 1).lastIndexOf("/");
1056:                } else {
1057:                    delimiterPosition = parentURL.lastIndexOf("/");
1058:                }
1059:
1060:                parentURL = parentURL.substring(0, delimiterPosition + 1);
1061:
1062:                if (parentLocalName.endsWith(File.separator)) {
1063:                    delimiterPosition = parentLocalName.substring(0,
1064:                            parentLocalName.length() - 1).lastIndexOf(
1065:                            File.separator);
1066:                } else {
1067:                    delimiterPosition = parentLocalName
1068:                            .lastIndexOf(File.separator);
1069:                }
1070:
1071:                parentLocalName = parentLocalName.substring(0,
1072:                        delimiterPosition + 1);
1073:
1074:                CollectionImpl parent = null;
1075:
1076:                try {
1077:                    URL url = new URL(getURL(), parentURL);
1078:                    parent = new CollectionImpl(url, parentLocalName, null);
1079:                } catch (java.net.MalformedURLException exc) {
1080:                    exc.printStackTrace();
1081:                }
1082:
1083:                return parent;
1084:            }
1085:
1086:            /** Get the URL of the collection containing this resource.
1087:             *
1088:             * @return the parent collection URL, always ending in a separator
1089:             * @exception com.ibm.webdav.WebDAVException
1090:             */
1091:            public URL getParentURL() throws WebDAVException {
1092:                String uri = getURL().getFile();
1093:                int delimiterPosition = 0;
1094:
1095:                if (uri.endsWith("/")) {
1096:                    delimiterPosition = uri.substring(0, uri.length() - 1)
1097:                            .lastIndexOf("/");
1098:                } else {
1099:                    delimiterPosition = uri.lastIndexOf("/");
1100:                }
1101:
1102:                URL parentURL = null;
1103:
1104:                try {
1105:                    parentURL = new URL(getURL(), uri.substring(0,
1106:                            delimiterPosition + 1));
1107:                } catch (java.net.MalformedURLException exc) {
1108:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
1109:                            "Malformed URL");
1110:                }
1111:
1112:                return parentURL;
1113:            }
1114:
1115:            public MultiStatus getSearchSchema(ResourceContext context,
1116:                    SearchRequest searchReq) throws WebDAVException {
1117:                this .context = context;
1118:
1119:                // create a MultiStatus to hold the results
1120:                MultiStatus results = new MultiStatus();
1121:
1122:                // create a document
1123:                Document document = null;
1124:
1125:                try {
1126:                    DocumentBuilderFactory factory = DocumentBuilderFactory
1127:                            .newInstance();
1128:                    factory.setNamespaceAware(true);
1129:
1130:                    DocumentBuilder docbuilder = factory.newDocumentBuilder();
1131:                    document = docbuilder.newDocument();
1132:                } catch (Exception e) {
1133:                    e.printStackTrace(System.err);
1134:                    throw new WebDAVException(WebDAVStatus.SC_PROCESSING, e
1135:                            .getMessage());
1136:                }
1137:
1138:                SearchSchema schema = searchManager.getSearchSchema(searchReq);
1139:
1140:                SchemaResponse response = new SchemaResponse(document, schema,
1141:                        searchReq.getScopeURI());
1142:
1143:                results.addResponse(response);
1144:
1145:                return results;
1146:            }
1147:
1148:            public MultiStatus executeSearch(ResourceContext context,
1149:                    SearchRequest searchReq) throws WebDAVException {
1150:                this .context = context;
1151:
1152:                // create a MultiStatus to hold the results
1153:                MultiStatus result = new MultiStatus();
1154:
1155:                if (searchManager.validate(searchReq)) {
1156:                    Vector resources = searchManager.executeSearch(searchReq,
1157:                            this );
1158:
1159:                    // now get the properties of the members if necessary
1160:                    Enumeration members = resources.elements();
1161:
1162:                    while (members.hasMoreElements()) {
1163:                        ResourceImpl member = (ResourceImpl) members
1164:                                .nextElement();
1165:
1166:                        try {
1167:                            MultiStatus memberResult = null;
1168:
1169:                            if (member.isCollection()) {
1170:                                if (searchReq.isAllSelectProperties()) {
1171:                                    memberResult = ((CollectionImpl) member)
1172:                                            .getProperties(context,
1173:                                                    Collection.this Resource);
1174:                                } else {
1175:                                    memberResult = ((CollectionImpl) member)
1176:                                            .getProperties(
1177:                                                    context,
1178:                                                    (PropertyName[]) searchReq
1179:                                                            .getSelectProperties()
1180:                                                            .toArray(
1181:                                                                    new PropertyName[0]),
1182:                                                    Collection.this Resource);
1183:                                }
1184:                            } else {
1185:                                if (searchReq.isAllSelectProperties()) {
1186:                                    memberResult = member
1187:                                            .getProperties(context);
1188:                                } else {
1189:                                    memberResult = member
1190:                                            .getProperties(
1191:                                                    context,
1192:                                                    (PropertyName[]) searchReq
1193:                                                            .getSelectProperties()
1194:                                                            .toArray(
1195:                                                                    new PropertyName[0]));
1196:                                }
1197:                            }
1198:
1199:                            result.mergeWith(memberResult);
1200:                        } catch (WebDAVException exc) {
1201:                            MethodResponse response = new MethodResponse(member
1202:                                    .getURL().toString(), exc.getStatusCode());
1203:                            result.addResponse(response);
1204:                        } catch (Exception e) {
1205:                            e.printStackTrace();
1206:                            throw new WebDAVException(
1207:                                    WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
1208:                                    "unable to get properties");
1209:                        }
1210:                    }
1211:                } else {
1212:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
1213:                            "Invalid query");
1214:                }
1215:
1216:                getResponseContext().contentType("text/xml");
1217:
1218:                return result;
1219:            }
1220:
1221:            /** Get all the properties of this resource.
1222:             *
1223:             * @return a MultiStatus of PropertyResponses. It should contain only one
1224:             * response element.
1225:             * @see com.ibm.webdav.MultiStatus
1226:             * @see com.ibm.webdav.PropertyResponse
1227:             * @exception com.ibm.webdav.WebDAVException
1228:             */
1229:            public MultiStatus getProperties(ResourceContext context)
1230:                    throws WebDAVException {
1231:                this .context = context;
1232:
1233:                // make sure the resource exists.
1234:                if (!(exists() || namespaceManager.isLockNull())) {
1235:
1236:                    throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
1237:                            "Resource does not exist");
1238:                }
1239:
1240:                setStatusCode(WebDAVStatus.SC_MULTI_STATUS);
1241:                getResponseContext().contentType("text/xml");
1242:
1243:                return propertiesManager.getProperties();
1244:            }
1245:
1246:            /** Get the named properties of this resource.
1247:             *
1248:             * @param names an arrary of property names to retrieve
1249:             *
1250:             * @return a MultiStatus of PropertyResponses
1251:             * @exception com.ibm.webdav.WebDAVException
1252:             * @see com.ibm.webdav.PropertyResponse
1253:             */
1254:            public MultiStatus getProperties(ResourceContext context,
1255:                    PropertyName[] names) throws WebDAVException {
1256:                this .context = context;
1257:
1258:                // make sure the resource exists.
1259:                if (!(exists() || namespaceManager.isLockNull())) {
1260:                    throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
1261:                            "Resource does not exist");
1262:                }
1263:
1264:                getResponseContext().contentType("text/xml");
1265:
1266:                return propertiesManager.getProperties(names);
1267:            }
1268:
1269:            /** Get the value of the given property for this resource.
1270:             *
1271:             * @param name the name of the property to retrieve
1272:             *
1273:             * @return PropertyValue or null if the resource does not have the requested property
1274:             * @exception com.ibm.webdav.WebDAVException
1275:             */
1276:            public PropertyValue getProperty(PropertyName name)
1277:                    throws WebDAVException {
1278:                PropertyName[] names = new PropertyName[1];
1279:                names[0] = name;
1280:
1281:                Enumeration responses = getProperties(context, names)
1282:                        .getResponses();
1283:                PropertyResponse response = (PropertyResponse) responses
1284:                        .nextElement();
1285:                Dictionary properties = response.getPropertiesByPropName();
1286:
1287:                return (PropertyValue) properties.get(name);
1288:            }
1289:
1290:            /** Get the names of all properties for this resource. The result is similar to
1291:             * getProperties(), but the properties have no values.
1292:             *
1293:             * @return a MultiStatus of PropertyResponses
1294:             * (PropertyValue.value is always null, PropertyValue.status contains the status)
1295:             * @exception com.ibm.webdav.WebDAVException
1296:             * @see com.ibm.webdav.PropertyResponse
1297:             */
1298:            public MultiStatus getPropertyNames(ResourceContext context)
1299:                    throws WebDAVException {
1300:                this .context = context;
1301:
1302:                // make sure the resource exists.
1303:                if (!(exists() || namespaceManager.isLockNull())) {
1304:                    throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
1305:                            "Resource does not exist");
1306:                }
1307:
1308:                getResponseContext().contentType("text/xml");
1309:
1310:                return propertiesManager.getPropertyNames();
1311:            }
1312:
1313:            /** Get the request context for this resource. The context contains information
1314:             * used by methods on a resource when the method is called.
1315:             *
1316:             * @return the HTTPHeaders providing information that controls
1317:             * method execution.
1318:             * @exception com.ibm.webdav.WebDAVException
1319:             */
1320:            public HTTPHeaders getRequestContext() throws WebDAVException {
1321:                return context.getRequestContext();
1322:            }
1323:
1324:            /** Get the response context for this resource. The context contains information
1325:             * returned from invocations of methods on a resource.
1326:             *
1327:             * @return the HTTPHeaders providing information that
1328:             * is returned by method execution.
1329:             * @exception com.ibm.webdav.WebDAVException
1330:             */
1331:            public HTTPHeaders getResponseContext() throws WebDAVException {
1332:                return context.getResponseContext();
1333:            }
1334:
1335:            /**
1336:             * Insert the method's description here.
1337:             * Creation date: (4/13/2000 8:53:11 PM)
1338:             * @return com.ibm.webdav.WebDAVStatus
1339:             */
1340:            public com.ibm.webdav.WebDAVStatus getStatusCode() {
1341:                return context.getStatusCode();
1342:            }
1343:
1344:            /** Get the name that identifies this resource.
1345:             *
1346:             * @return the URL for this resource
1347:             * @exception com.ibm.webdav.WebDAVException
1348:             */
1349:            public URL getURL() throws WebDAVException {
1350:                return url;
1351:            }
1352:
1353:            /** Is this resource locked with the given lock token?
1354:             * @param lockToken the lock token to check for
1355:             * @exception com.ibm.webdav.WebDAVException
1356:             */
1357:            protected boolean hasLock(String lockToken) throws WebDAVException {
1358:                boolean hasLock = false;
1359:                Enumeration locks = getLocks().elements();
1360:
1361:                while (!hasLock && locks.hasMoreElements()) {
1362:                    ActiveLock lock = (ActiveLock) locks.nextElement();
1363:                    hasLock = lock.getLockToken().equals(lockToken);
1364:                }
1365:
1366:                return hasLock;
1367:            }
1368:
1369:            /** Check for a valid URI
1370:             * @return true if this resource has a valid URI
1371:             * @exception com.ibm.webdav.WebDAVException
1372:             */
1373:            public boolean hasValidURI() throws WebDAVException {
1374:                return getName() != null;
1375:            }
1376:
1377:            /** Inherit all deep locks on the parent of this resource.
1378:             * @exception com.ibm.webdav.WebDAVException
1379:             */
1380:            protected void inheritParentDeepLocks() throws WebDAVException {
1381:                CollectionImpl parent = (CollectionImpl) getParentCollection();
1382:
1383:                Enumeration parentLocks = parent.getLocks().elements();
1384:
1385:                while (parentLocks.hasMoreElements()) {
1386:                    ActiveLock parentLock = (ActiveLock) parentLocks
1387:                            .nextElement();
1388:
1389:                    if (parentLock.getDepth().equals(Collection.deep)) {
1390:                        if (!hasLock(parentLock.getLockToken())) {
1391:                            lock(parentLock);
1392:                        }
1393:                    }
1394:                }
1395:            }
1396:
1397:            /** Returns true if this Resource is a collection. Returns false otherwise.
1398:             *
1399:             * @return true if this Resource is a collection.
1400:             * @exception com.ibm.webdav.WebDAVException
1401:             */
1402:            public boolean isCollection() throws WebDAVException {
1403:                return namespaceManager.isCollection();
1404:            }
1405:
1406:            /** See if this resource is locked.
1407:             *
1408:             * @return true if this resource is locked, false otherwise.
1409:             * @exception com.ibm.webdav.WebDAVException
1410:             */
1411:            public boolean isLocked() throws WebDAVException {
1412:                // see if there are any active locks
1413:                return !getLocks().isEmpty();
1414:            }
1415:
1416:            /** Is this resource locked by the current authorized user? That is, does the
1417:             * current user have sufficient locking access to modify this resource. The
1418:             * method, like all methods that do modify the resource, must have a precondition
1419:             * set in the context containing the lock token of the resource owned by this
1420:             * user. The user is set in the request context using the authorization method.
1421:             * @return true if this resource is locked by the principal in the context
1422:             *    sufficient to modify the resource.
1423:             * @exception com.ibm.webdav.WebDAVException
1424:             * @see com.ibm.webdav.ResourceContext#authorization
1425:             */
1426:            public boolean isLockedByMe() throws WebDAVException {
1427:                String principal = getRequestContext().getAuthorizationId();
1428:                Precondition precondition = getRequestContext().precondition();
1429:
1430:                if (precondition == null) {
1431:                    return false; // it is not locked by me, or the server doesn't know
1432:
1433:                    //throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST, "Missing If header containing lock token");
1434:                }
1435:
1436:                // get the locks on this resource
1437:                Enumeration locks = getLocks().elements();
1438:                boolean isLockedByMe = false;
1439:
1440:                // look for a matching lock
1441:                while (locks.hasMoreElements()) {
1442:                    ActiveLock activeLock = (ActiveLock) locks.nextElement();
1443:                    Condition condition = new Condition(getURL().getFile());
1444:                    ConditionTerm term = new ConditionTerm();
1445:                    StateToken stateToken = new StateToken(activeLock
1446:                            .getLockToken());
1447:                    term.addConditionFactor(stateToken);
1448:                    condition.addConditionTerm(term);
1449:
1450:                    if (precondition.matches(condition)
1451:                            && activeLock.getPrincipal().equals(principal)
1452:                            && activeLock.getLockType().equals(
1453:                                    ActiveLock.writeLock)) {
1454:                        isLockedByMe = true;
1455:
1456:                        break;
1457:                    }
1458:                }
1459:
1460:                return isLockedByMe;
1461:            }
1462:
1463:            /** See if the target URL has the same host and port (e.g., the same server)
1464:             * as this resource. Matches on the host name, not its Internet address.
1465:             *
1466:             * @target the URL of the target resource
1467:             *
1468:             * @return true if the target is supported by the same server
1469:             */
1470:            public boolean isSameServerAs(URL target) {
1471:                return target.getHost().equals(url.getHost())
1472:                        && (target.getPort() == url.getPort());
1473:            }
1474:
1475:            /** Load properties from the properties manager and update live properties.
1476:             *
1477:             * @return an XML document containing a properties element.
1478:             * @exception com.ibm.webdav.WebDAVException
1479:             */
1480:            public Document loadProperties() throws WebDAVException {
1481:                Document propertiesDocument = propertiesManager
1482:                        .loadProperties();
1483:                updateLiveProperties(propertiesDocument);
1484:                if (propertiesManager instanceof  VersionedPropertiesManager) {
1485:                    if (((VersionedNamespaceManager) namespaceManager)
1486:                            .isVersioned() == true) {
1487:                        ((VersionedPropertiesManager) propertiesManager)
1488:                                .updateVersionProperties(propertiesDocument);
1489:                    }
1490:                }
1491:
1492:                return propertiesDocument;
1493:            }
1494:
1495:            /** Lock this resource with the information contained in the given active lock.
1496:             * @param activeLock information about the lock
1497:             * @return a MultiStatus containing a lockdiscovery property indicating
1498:             * @exception com.ibm.webdav.WebDAVException
1499:             */
1500:            protected MultiStatus lock(ActiveLock activeLock)
1501:                    throws WebDAVException {
1502:                // get the locks on this resource
1503:                Enumeration locks = getLocks().elements();
1504:
1505:                while (locks.hasMoreElements()) {
1506:                    ActiveLock lock = (ActiveLock) locks.nextElement();
1507:
1508:                    if (lock.getScope().equals(ActiveLock.exclusive)) {
1509:                        throw new WebDAVException(WebDAVStatus.SC_LOCKED,
1510:                                "Resource has an exclusive lock");
1511:                    }
1512:
1513:                    if (lock.getScope().equals(ActiveLock.shared)
1514:                            && activeLock.getScope().equals(
1515:                                    ActiveLock.exclusive)) {
1516:                        throw new WebDAVException(WebDAVStatus.SC_LOCKED,
1517:                                "Resource already has a shared lock");
1518:                    }
1519:
1520:                    if (lock.getScope().equals(ActiveLock.shared)
1521:                            && lock.getPrincipal().equals(
1522:                                    activeLock.getPrincipal())) {
1523:                        throw new WebDAVException(WebDAVStatus.SC_LOCKED,
1524:                                "The principal already has a lock on this resource");
1525:                    }
1526:                }
1527:
1528:                return lockManager.lock(activeLock);
1529:            }
1530:
1531:            /** Lock this resource based on the given parameters. This allows control of
1532:             * the lock scope (exclusive or shared) the lock type (write), owner information, etc.
1533:             *
1534:             * @param scope the scope of the lock, exclusive or shared
1535:             * @param type the type of the lock, currently only write
1536:             * @param timeout the number of seconds before the lock times out or
1537:             *     -1 for infinite timeout.
1538:             * @param owner an XML element containing useful information that can be
1539:             *     used to identify the owner of the lock. An href to a home page, an
1540:             *     email address, phone number, etc. Can be null if no owner information
1541:             *     is provided.
1542:             *
1543:             * @return a MultiStatus containing a lockdiscovery property indicating
1544:             * the results of the lock operation.
1545:             * @exception com.ibm.webdav.WebDAVException
1546:             */
1547:            public MultiStatus lock(ResourceContext context, String scope,
1548:                    String type, int timeout, Element owner)
1549:                    throws WebDAVException {
1550:                this .context = context;
1551:
1552:                ActiveLock activeLock = getActiveLockFor(scope, type, timeout,
1553:                        owner);
1554:                MultiStatus result = lock(activeLock);
1555:
1556:                // return the granted lock token in the lockToken response context
1557:                getResponseContext().lockToken(activeLock.getLockToken());
1558:                getResponseContext().contentType("text/xml");
1559:
1560:                return result;
1561:            }
1562:
1563:            /** Startup an RMI server for a ResourceImpl. The URL would most likely be for
1564:             * some root WebDAV collection corresponding to the doc.root of a typical web
1565:             * server. The resource identified by the URL must exist.
1566:             * @param args root URL, its local file pathname
1567:             */
1568:            public static void main(String[] args) {
1569:                // get the URL of the resource to export
1570:                if (args.length != 2) {
1571:                    System.err
1572:                            .println("Usage: java ResourceImpl url localName");
1573:                    System.exit(-1);
1574:                }
1575:
1576:                // Create a ResourceImpl, export it, and bind it in the RMI Registry
1577:                try {
1578:                    URL url = new URL(args[0]);
1579:                    String localName = args[1];
1580:
1581:                    // Create and install a security manager
1582:                    System.setSecurityManager(new RMISecurityManager());
1583:
1584:                    ResourceImpl resource = ResourceImpl.create(url, localName);
1585:
1586:                    // strip the protocol off the URL for the registered name
1587:                    String name = url.toString();
1588:                    name = name.substring(name.indexOf(":") + 1);
1589:                    Naming.rebind(name, resource);
1590:
1591:                } catch (Exception exc) {
1592:                    System.err.println("ResourceImpl error: "
1593:                            + exc.getMessage());
1594:                    exc.printStackTrace();
1595:                    System.exit(-1);
1596:                }
1597:            } // main
1598:
1599:            public MultiStatus createBinding(ResourceContext context,
1600:                    String bindName, String resourceURI) throws WebDAVException {
1601:                this .context = context;
1602:
1603:                setStatusCode(WebDAVStatus.SC_CREATED);
1604:
1605:                MultiStatus result = new MultiStatus();
1606:
1607:                try {
1608:                    // validate the uri
1609:                    if (!hasValidURI()) {
1610:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
1611:                                "Invalid URI");
1612:                    }
1613:
1614:                    // make sure the resource exists
1615:                    if (!exists()) {
1616:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
1617:                                "Cannot copy a lock-null resource");
1618:                    }
1619:
1620:                    //make sure the resource is a collection
1621:                    if (isCollection() == false) {
1622:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
1623:                                "URI indentified in BIND request must be an existing collection");
1624:                    }
1625:
1626:                    // the destination may be a relative URL
1627:                    StringBuffer strbuf = new StringBuffer();
1628:                    strbuf.append(url.toExternalForm());
1629:
1630:                    if (strbuf.toString().endsWith("/") == false) {
1631:                        strbuf.append("/");
1632:                    }
1633:                    strbuf.append(bindName);
1634:
1635:                    Resource destination = new Resource(strbuf.toString());
1636:
1637:                    Resource bindSource = new Resource(resourceURI);
1638:
1639:                    // are the source and destination the same?
1640:                    if (bindSource.equals(destination)) {
1641:                        throw new WebDAVException(WebDAVStatus.SC_FORBIDDEN,
1642:                                "Can't copy source on top of itself");
1643:                    }
1644:
1645:                    destination.getRequestContext().precondition(
1646:                            getRequestContext().precondition());
1647:                    destination.getRequestContext().authorization(
1648:                            getRequestContext().authorization());
1649:
1650:                    if (destination.exists()) {
1651:                        throw new WebDAVException(
1652:                                WebDAVStatus.SC_PRECONDITION_FAILED,
1653:                                "Destination exists and overwrite not specified");
1654:                    }
1655:
1656:                    this .namespaceManager.createBinding(bindName, new URL(
1657:                            resourceURI));
1658:
1659:                    // everything must have gone OK, there
1660:                    // is no response for a successful delete
1661:                    getResponseContext().contentType("text/xml");
1662:                } catch (WebDAVException exc) {
1663:                    throw exc;
1664:                } catch (java.net.MalformedURLException exc) {
1665:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
1666:                            "Malformed URL");
1667:                } catch (java.io.IOException exc) {
1668:                    throw new WebDAVException(
1669:                            WebDAVStatus.SC_INTERNAL_SERVER_ERROR, "IO Error");
1670:                }
1671:
1672:                return result;
1673:            }
1674:
1675:            /** Move this resource to the destination URL.
1676:             * Partial results are possible, check the returned status for details
1677:             *
1678:             * @param destinationURL the destination
1679:             * @param overwrite true implies overrite the destination if it exists
1680:             * @param propertiesToMove a collection of properties that must be moved or
1681:             * the method will fail. propertiesToMove may have one of the following values:
1682:             * <ul>
1683:             *    <li>null - ignore properties that cannot be moved</li>
1684:             *    <li>empty collection - all properties must be moved or the method will fail</li>
1685:             *    <li>a collection of URIs - a list of the properties that must be moved
1686:             *        or the method will fail</li>
1687:             * </ul>
1688:             *
1689:             * @return the status of the move operation for each resource moved
1690:             * @exception com.ibm.webdav.WebDAVException
1691:             */
1692:            public MultiStatus move(ResourceContext context,
1693:                    String destinationURL, boolean overwrite,
1694:                    Vector propertiesToMove) throws WebDAVException {
1695:                this .context = context;
1696:
1697:                MultiStatus result = new MultiStatus();
1698:
1699:                if (webdavProperties.getProperty("atomicmove")
1700:                        .equalsIgnoreCase("true")) {
1701:
1702:                    // check to see if the resource is locked by another user
1703:                    if (isLocked() && !isLockedByMe()) {
1704:                        throw new WebDAVException(WebDAVStatus.SC_LOCKED,
1705:                                "Resource is locked by another user");
1706:                    }
1707:
1708:                    result = atomicMove(context, destinationURL, overwrite);
1709:
1710:                    Enumeration propertyNames = context.getResponseContext()
1711:                            .keys();
1712:                } else {
1713:                    // proceed with the move even if the source is locked by
1714:                    // another principal. Best effort will perform the copy but
1715:                    // not the delete.
1716:                    result = copy(context, destinationURL, overwrite,
1717:                            propertiesToMove);
1718:
1719:                    ResourceContext copyContext = context;
1720:                    WebDAVStatus oldStatus = context.getStatusCode();
1721:                    result.mergeWith(delete(context));
1722:
1723:                    if (getStatusCode().getStatusCode() == 204) {
1724:                        // it was a clean delete that doesn't affect the
1725:                        //     final result code.
1726:                        context.setStatusCode(oldStatus);
1727:                    }
1728:
1729:                    Enumeration propertyNames = copyContext
1730:                            .getResponseContext().keys();
1731:
1732:                    while (propertyNames.hasMoreElements()) {
1733:                        String name = (String) propertyNames.nextElement();
1734:                        String value = (String) copyContext
1735:                                .getResponseContext().get(name);
1736:
1737:                        if (!context.getResponseContext().containsKey(name)) {
1738:                            getResponseContext().put(name, value);
1739:                        }
1740:                    }
1741:                }
1742:
1743:                getResponseContext().contentType("text/xml");
1744:
1745:                return result;
1746:            }
1747:
1748:            /** Is the parent of this resource depth locked with the given lock token?
1749:             * @param lockToken the lock token to check
1750:             * @return true if the parant of this resource is locked with the lock token
1751:             * @exception com.ibm.webdav.WebDAVException
1752:             */
1753:            public boolean parentIsLockedWith(String lockToken)
1754:                    throws WebDAVException {
1755:                // get the locks on the parent of this resource
1756:                boolean isLocked = false;
1757:                CollectionImpl parent = null;
1758:
1759:                try {
1760:                    parent = (CollectionImpl) getParentCollection();
1761:                } catch (Exception exc) {
1762:                }
1763:
1764:                if (parent != null) {
1765:                    Enumeration locks = parent.getLocks().elements();
1766:
1767:                    // look for a matching lock
1768:                    while (locks.hasMoreElements()) {
1769:                        ActiveLock activeLock = (ActiveLock) locks
1770:                                .nextElement();
1771:
1772:                        if (activeLock.getLockToken().equals(lockToken)) {
1773:                            isLocked = true;
1774:
1775:                            break;
1776:                        }
1777:                    }
1778:                }
1779:
1780:                return isLocked;
1781:            }
1782:
1783:            /** This method treats this resource as a method or service, and sends its parameter to
1784:             * this resource where it is handled in a resource-specific way. For example,
1785:             * sending data from an HTML form to a URL representing a Servlet or CGI script that processes
1786:             * the form data to produce some result.
1787:             *
1788:             * @param args a string representing the arguments to the method represented by this URL. The
1789:             * arguments are in the form ?parameterName1=value1&amp;parameterName2=value2... as specified
1790:             * for URL queries.
1791:             *
1792:             * @return the results of sending the arguments to the URL
1793:             * @exception com.ibm.webdav.WebDAVException
1794:             */
1795:            public byte[] performWith(ResourceContext context, String args)
1796:                    throws WebDAVException {
1797:                this .context = context;
1798:
1799:                return namespaceManager.performWith(args);
1800:            }
1801:
1802:            /** Refresh the lock on this resource by resetting the lock timeout.
1803:             * The context must contain the proper authorization for the requesting
1804:             * principal.
1805:             *
1806:             * @param lockToken the lock token identifying the lock.
1807:             * @param timeout the new timeout in seconds. -1 means infinite timeout.
1808:             *
1809:             * @return updated information about the lock status of this resource
1810:             * @exception com.ibm.webdav.WebDAVException
1811:             */
1812:            public MultiStatus refreshLock(ResourceContext context,
1813:                    String lockToken, int timeout) throws WebDAVException {
1814:                this .context = context;
1815:
1816:                String principal = getRequestContext().getAuthorizationId();
1817:
1818:                // find the lock
1819:                ActiveLock lockToRefresh = null;
1820:                Enumeration activeLocks = getLocks().elements();
1821:
1822:                while (activeLocks.hasMoreElements()) {
1823:                    ActiveLock activeLock = (ActiveLock) activeLocks
1824:                            .nextElement();
1825:
1826:                    if (activeLock.getLockToken().equals(lockToken)
1827:                            && (activeLock.getPrincipal().equals(principal)
1828:                                    || principal.equals("root") || ResourceImpl.authenticator
1829:                                    .isSuperUser(this ) == true)) {
1830:                        lockToRefresh = activeLock;
1831:
1832:                        break;
1833:                    }
1834:                }
1835:
1836:                if (lockToRefresh == null) {
1837:                    throw new WebDAVException(
1838:                            WebDAVStatus.SC_PRECONDITION_FAILED,
1839:                            "principal does not own a lock");
1840:                }
1841:
1842:                // finally, reset the lock.
1843:                lockToRefresh.setTimeout(timeout);
1844:                getResponseContext().contentType("text/xml");
1845:
1846:                return lockManager.refreshLock(lockToRefresh);
1847:            }
1848:
1849:            /** Remove the live DAV properties from the properties document. There is no
1850:             * reason to save them as they are recalculated each time the properties are
1851:             * loaded.
1852:             * @param propertiesDocument an XML document containing the current resource properties
1853:             */
1854:            public void removeLiveProperties(Document propertiesDocument) {
1855:                Element properties = (Element) propertiesDocument
1856:                        .getDocumentElement();
1857:                Element p = null;
1858:                p = (Element) ((Element) properties).getElementsByTagNameNS(
1859:                        "DAV:", "supportedlock").item(0);
1860:
1861:                if (p != null) {
1862:                    properties.removeChild(p);
1863:                }
1864:
1865:                // remove the live properties that are repository specific
1866:                propertiesManager.removeLiveProperties(propertiesDocument);
1867:            }
1868:
1869:            /** Save the properties after removing any live properties that don't need
1870:             * to be saved.
1871:             * @param propertiesDocument an XML document containing the resource's properties
1872:             * @exception com.ibm.webdav.WebDAVException
1873:             */
1874:            public void saveProperties(Document propertiesDocument)
1875:                    throws WebDAVException {
1876:                // don't save the live properties, they will be recalculated on each load
1877:                removeLiveProperties(propertiesDocument);
1878:                if (propertiesManager instanceof  VersionedPropertiesManager) {
1879:                    // don't save versoined properties, they will be recalculated on each load
1880:                    ((VersionedPropertiesManager) propertiesManager)
1881:                            .removeVersionProperties(propertiesDocument);
1882:                }
1883:
1884:                propertiesManager.saveProperties(propertiesDocument);
1885:            }
1886:
1887:            /** Set the contents of this resource. This may create a new resource on the server,
1888:             * or update the contents of an existing resource. Sufficient authorization is required
1889:             * and administered by the target web server. For text/* MIME types, the caller should
1890:             * be sure to convert Strings to byte codes using an acceptable charset, and to set
1891:             * that charset in the request context so the server knows how to decode the byte
1892:             * stream.
1893:             *
1894:             * @param value the new contents for the resource
1895:             * @exception com.ibm.webdav.WebDAVException
1896:             */
1897:            public void setContents(byte[] value) throws WebDAVException {
1898:                BufferedOutputStream os = (BufferedOutputStream) getContentsOutputStream(context);
1899:
1900:                for (int i = 0; i < value.length; i++) {
1901:                    try {
1902:                        os.write(value[i]);
1903:                    } catch (WebDAVException exc) {
1904:                        throw exc;
1905:                    } catch (java.io.IOException exc) {
1906:                        throw new WebDAVException(
1907:                                WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
1908:                                "IO Error");
1909:                    }
1910:                }
1911:
1912:                closeContentsOutputStream(context);
1913:            }
1914:
1915:            /**
1916:             * Insert the method's description here.
1917:             * Creation date: (4/14/2000 4:14:55 PM)
1918:             * @param newContext com.ibm.webdav.ResourceContext
1919:             */
1920:            void setContext(com.ibm.webdav.ResourceContext newContext) {
1921:                context = newContext;
1922:            }
1923:
1924:            /** Edit the properties of a resource. The updates must refer to a Document containing a WebDAV
1925:             * DAV:propertyupdates element as the document root.
1926:             *
1927:             * @param updates an XML Document containing DAV:propertyupdate elements
1928:             * describing the edits to be made
1929:             * @return a MultiStatus indicating the status of the updates
1930:             * @exception com.ibm.webdav.WebDAVException
1931:             */
1932:            public MultiStatus setProperties(ResourceContext context,
1933:                    Document updates) throws WebDAVException {
1934:                this .context = context;
1935:
1936:                // make sure the resource exists.
1937:                if (!exists()) {
1938:                    throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
1939:                            "Resource does not exist");
1940:                }
1941:
1942:                // check to see if the resource is locked by another user
1943:                if (isLocked() && !isLockedByMe()) {
1944:                    return createPropPatchMultiStatus(new WebDAVException(
1945:                            WebDAVStatus.SC_LOCKED,
1946:                            "Resource is locked by another user"), updates);
1947:                }
1948:
1949:                getResponseContext().contentType("text/xml");
1950:
1951:                return propertiesManager.setProperties(updates);
1952:            }
1953:
1954:            /**
1955:             * Insert the method's description here.
1956:             * Creation date: (4/13/2000 8:48:11 PM)
1957:             * @param newRequestContext com.ibm.webdav.ResourceContext
1958:             */
1959:            public void setRequestContext(ResourceContext newRequestContext) {
1960:                context
1961:                        .setRequestContext(newRequestContext
1962:                                .getRequestContext());
1963:            }
1964:
1965:            /**
1966:             * Insert the method's description here.
1967:             * Creation date: (4/13/2000 8:48:11 PM)
1968:             * @param newResponseContext com.ibm.webdav.ResourceContext
1969:             */
1970:            public void setResponseContext(
1971:                    com.ibm.webdav.ResourceContext newResponseContext) {
1972:                context.setResponseContext(newResponseContext
1973:                        .getResponseContext());
1974:            }
1975:
1976:            /**
1977:             * Insert the method's description here.
1978:             * Creation date: (4/13/2000 8:53:11 PM)
1979:             * @param newStatusCode com.ibm.webdav.WebDAVStatus
1980:             */
1981:            void setStatusCode(int newStatusCode) {
1982:                context.getStatusCode().setStatusCode(newStatusCode);
1983:            }
1984:
1985:            /**
1986:             * Insert the method's description here.
1987:             * Creation date: (4/13/2000 8:53:11 PM)
1988:             * @param newStatusCode com.ibm.webdav.WebDAVStatus
1989:             */
1990:            void setStatusCode(com.ibm.webdav.WebDAVStatus newStatusCode) {
1991:                context.getStatusCode().setStatusCode(
1992:                        newStatusCode.getStatusCode());
1993:            }
1994:
1995:            /** Translate the URI reference relative to this resource in order to obtain
1996:             * the real path name if the URI references a resource on the same machine.
1997:             *
1998:             * @param target the URL of the path to translate
1999:             *
2000:             * @return the pathname to the file on this machine, or the URL if the file
2001:             * is not on this machine
2002:             * @exception com.ibm.webdav.WebDAVException
2003:             */
2004:            public String translatePathRelativeToMe(String target)
2005:                    throws WebDAVException {
2006:                String result = target;
2007:                URL targetURL = null;
2008:
2009:                try {
2010:                    targetURL = new URL(url, target);
2011:                } catch (java.net.MalformedURLException exc) {
2012:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2013:                            "malformed target URL");
2014:                }
2015:
2016:                if (targetURL.getHost().equals(url.getHost())) {
2017:                    // is on this machine, convert the target to a file on this machine
2018:                    result = targetURL.getFile().replace('/',
2019:                            File.separatorChar);
2020:
2021:                    // append it to doc.root
2022:                    String uri = url.getFile();
2023:                    String docRoot = fileName.substring(0, fileName.length()
2024:                            - uri.length());
2025:                    result = docRoot + result;
2026:                }
2027:
2028:                return result;
2029:            }
2030:
2031:            /** Unlock the lock identified by the lockToken on this resource
2032:             *
2033:             * @param lockToken the lock token obtained from the ActiveLock of a previous <code>lock() </code>
2034:             *     or <code>getLocks()</code>.
2035:             *
2036:             * @return a MultiStatus containing any responses on resources that could not
2037:             *     be unlocked.
2038:             * @exception com.ibm.webdav.WebDAVException
2039:             */
2040:            public MultiStatus unlock(ResourceContext context, String lockToken)
2041:                    throws WebDAVException {
2042:                this .context = context;
2043:
2044:                // first, is this the root parent collection locked by this lockToken
2045:                if (parentIsLockedWith(lockToken)) {
2046:                    throw new WebDAVException(
2047:                            WebDAVStatus.SC_METHOD_NOT_ALLOWED,
2048:                            "Must unlock depth lock from root collection having the lock.");
2049:                }
2050:
2051:                MultiStatus result = doUnlock(lockToken);
2052:                setStatusCode(WebDAVStatus.SC_NO_CONTENT); // the default status code
2053:
2054:                return result;
2055:            }
2056:
2057:            /** Update live properties that are supported by this server. This method
2058:             * updates those that are not unique to any repository implementation.
2059:             * This is mostly the live DAV properties as defined in the WebDAV spec.
2060:             * @param document an XML document containing the resource properties
2061:             * @exception com.ibm.webdav.WebDAVException
2062:             */
2063:            public void updateLiveProperties(Document document)
2064:                    throws WebDAVException {
2065:                Element properties = document.getDocumentElement();
2066:
2067:                // remove any live properties that need to be recalculated
2068:                removeLiveProperties(document);
2069:
2070:                // now recalculate the live properties, the repository independent ones first
2071:                Enumeration liveprops = liveProperties.elements();
2072:
2073:                while (liveprops.hasMoreElements()) {
2074:                    LiveProperty liveProperty = (LiveProperty) liveprops
2075:                            .nextElement();
2076:                    PropertyValue value = liveProperty.getValueFor(this );
2077:                    Element e = (Element) ((Element) properties)
2078:                            .getElementsByTagNameNS(liveProperty.getNSName(),
2079:                                    liveProperty.getNSLocalName()).item(0);
2080:
2081:                    if ((e != null) && (value != null)
2082:                            && (value.getValue() != null)) {
2083:                        properties.removeChild(e);
2084:                    }
2085:
2086:                    if ((value != null) && (value.getValue() != null)) {
2087:                        properties.appendChild(value.getValue());
2088:                    } else {
2089:                        // put in an empty element
2090:                        e = document.createElementNS(liveProperty.getNSName(),
2091:                                liveProperty.getPreferredPrefix() + ":"
2092:                                        + liveProperty.getNSLocalName());
2093:
2094:                        e.setAttribute("xmlns:"
2095:                                + liveProperty.getPreferredPrefix(),
2096:                                liveProperty.getNSName());
2097:                        properties.appendChild(e);
2098:                    }
2099:
2100:                    // TODO: missing status
2101:                }
2102:
2103:                // lockdiscovery
2104:
2105:                /*
2106:                Element lockdiscovery = (TXElement) lockManager.getLockDiscovery();
2107:                Element l = ((TXElement) properties).getElementNamed("DAV:", "lockdiscovery");
2108:                if (l != null && lockdiscovery != null) {
2109:                properties.removeChild(l);
2110:                }
2111:                properties.appendChild(lockdiscovery);
2112:                 */
2113:
2114:                // creationdate
2115:                Element creationDate = (Element) ((Element) properties)
2116:                        .getElementsByTagNameNS("DAV:", "creationdate").item(0);
2117:
2118:                if (creationDate == null) {
2119:                    creationDate = document.createElementNS("DAV:",
2120:                            "D:creationdate");
2121:
2122:                    String cdstring = new SimpleISO8601DateFormat()
2123:                            .format(new java.util.Date());
2124:                    creationDate.appendChild(document.createTextNode(cdstring));
2125:                    properties.appendChild(creationDate);
2126:                }
2127:
2128:                // displayname - set the default. Subclasses may want to override
2129:                Element displayName = (Element) ((Element) properties)
2130:                        .getElementsByTagNameNS("DAV:", "displayname").item(0);
2131:
2132:                if (displayName == null) {
2133:                    displayName = document.createElementNS("DAV:",
2134:                            "D:displayname");
2135:
2136:                    displayName.appendChild(document.createTextNode(URLEncoder
2137:                            .encode(getName())));
2138:                    properties.appendChild(displayName);
2139:                }
2140:
2141:                // get the supportedlock element from the lock manager
2142:                properties.appendChild(document.importNode(lockManager
2143:                        .getSupportedLock(), true));
2144:
2145:                // do the ones that are repository specific
2146:                propertiesManager.updateLiveProperties(document);
2147:            }
2148:
2149:            /**
2150:             * Checks in current resource
2151:             * 
2152:             * @throws WebDAVException
2153:             */
2154:            public void checkin() throws WebDAVException {
2155:                if (namespaceManager instanceof  VersionedNamespaceManager) {
2156:                    //			validate the uri
2157:                    if (hasValidURI() == false) {
2158:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2159:                                "Invalid URI");
2160:                    }
2161:
2162:                    // make sure the resource exists
2163:                    if (exists() == false) {
2164:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
2165:                                "Cannot copy a lock-null resource");
2166:                    }
2167:
2168:                    if (((VersionedNamespaceManager) namespaceManager)
2169:                            .isCheckedOutVersion() == false) {
2170:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2171:                                "Not checked out");
2172:                    }
2173:
2174:                    // check to see if the resource is locked by another user
2175:                    if (isLocked() && !isLockedByMe()) {
2176:                        throw new WebDAVException(WebDAVStatus.SC_LOCKED,
2177:                                "Resource is locked by another user");
2178:                    }
2179:
2180:                    String sLoc = ((VersionedNamespaceManager) namespaceManager)
2181:                            .checkin();
2182:                    context.getResponseContext().location(sLoc);
2183:                    setStatusCode(WebDAVStatus.SC_CREATED);
2184:                } else {
2185:                    throw new WebDAVException(
2186:                            WebDAVStatus.SC_METHOD_NOT_ALLOWED,
2187:                            "Repository does not support this method");
2188:                }
2189:            }
2190:
2191:            /**
2192:             * Checks out the current resource
2193:             * 
2194:             * @throws WebDAVException
2195:             */
2196:            public void checkout() throws WebDAVException {
2197:                if (namespaceManager instanceof  VersionedNamespaceManager) {
2198:                    //			validate the uri
2199:                    if (hasValidURI() == false) {
2200:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2201:                                "Invalid URI");
2202:                    }
2203:
2204:                    // make sure the resource exists
2205:                    if (exists() == false) {
2206:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
2207:                                "Cannot copy a lock-null resource");
2208:                    }
2209:
2210:                    // check to see if the resource is locked by another user
2211:                    if (isLocked() && !isLockedByMe()) {
2212:                        throw new WebDAVException(WebDAVStatus.SC_LOCKED,
2213:                                "Resource is locked by another user");
2214:                    }
2215:
2216:                    ((VersionedNamespaceManager) namespaceManager).checkout();
2217:                    setStatusCode(WebDAVStatus.SC_OK);
2218:                } else {
2219:                    throw new WebDAVException(
2220:                            WebDAVStatus.SC_METHOD_NOT_ALLOWED,
2221:                            "Repository does not support this method");
2222:                }
2223:            }
2224:
2225:            /**
2226:             * Get the named properties for all versions of this resource.
2227:             *
2228:             * @param context
2229:             * @param names an array of PropertyNames to retrieve.
2230:             * 
2231:             * @return
2232:             * @throws WebDAVException
2233:             */
2234:            public MultiStatus getVersionTreeReport(ResourceContext context,
2235:                    PropertyName[] names) throws WebDAVException {
2236:                this .context = context;
2237:
2238:                // check the depth parameter
2239:                if (namespaceManager.isVersionable() == false) {
2240:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2241:                            "Invalid depth on copy");
2242:                }
2243:                MultiStatus result = new MultiStatus();
2244:                // now get the properties of the versions if necessary
2245:
2246:                Iterator memberIter = ((VersionedNamespaceManager) namespaceManager)
2247:                        .getVersions().iterator();
2248:                while (memberIter.hasNext()) {
2249:                    ResourceImpl member = (ResourceImpl) memberIter.next();
2250:                    try {
2251:                        MultiStatus memberResult = member.getProperties(
2252:                                context, names);
2253:
2254:                        result.mergeWith(memberResult);
2255:                    } catch (WebDAVException exc) {
2256:                        MethodResponse response = new MethodResponse(member
2257:                                .getURL().toString(), exc.getStatusCode());
2258:                        result.addResponse(response);
2259:                    } catch (Exception e) {
2260:                        e.printStackTrace();
2261:                        throw new WebDAVException(
2262:                                WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
2263:                                "unable to delete resource");
2264:                    }
2265:                }
2266:
2267:                getResponseContext().contentType("text/xml");
2268:                return result;
2269:
2270:            }
2271:
2272:            /**
2273:             * Get the properties for all versions of this resource.
2274:             * 
2275:             * @param context
2276:             * @return
2277:             * @throws WebDAVException
2278:             */
2279:            public MultiStatus getVersionTreeReport(ResourceContext context)
2280:                    throws WebDAVException {
2281:                this .context = context;
2282:
2283:                // check the depth parameter
2284:                if (namespaceManager.isVersionable() == false) {
2285:                    throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2286:                            "Invalid depth on copy");
2287:                }
2288:                MultiStatus result = new MultiStatus();
2289:                // now get the properties of the versions if necessary
2290:
2291:                Iterator memberIter = ((VersionedNamespaceManager) namespaceManager)
2292:                        .getVersions().iterator();
2293:                while (memberIter.hasNext()) {
2294:                    ResourceImpl member = (ResourceImpl) memberIter.next();
2295:                    try {
2296:                        MultiStatus memberResult = member
2297:                                .getProperties(context);
2298:
2299:                        result.mergeWith(memberResult);
2300:                    } catch (WebDAVException exc) {
2301:                        MethodResponse response = new MethodResponse(member
2302:                                .getURL().toString(), exc.getStatusCode());
2303:                        result.addResponse(response);
2304:                    } catch (Exception e) {
2305:                        e.printStackTrace();
2306:                        throw new WebDAVException(
2307:                                WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
2308:                                "unable to delete resource");
2309:                    }
2310:                }
2311:
2312:                getResponseContext().contentType("text/xml");
2313:                return result;
2314:
2315:            }
2316:
2317:            /**
2318:             * 
2319:             */
2320:            public void uncheckout() throws WebDAVException {
2321:                if (namespaceManager instanceof  VersionedNamespaceManager) {
2322:                    //			validate the uri
2323:                    if (hasValidURI() == false) {
2324:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2325:                                "Invalid URI");
2326:                    }
2327:
2328:                    // make sure the resource exists
2329:                    if (exists() == false) {
2330:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
2331:                                "Cannot copy a lock-null resource");
2332:                    }
2333:
2334:                    if (((VersionedNamespaceManager) namespaceManager)
2335:                            .isCheckedOutVersion() == false) {
2336:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2337:                                "Not checked out");
2338:                    }
2339:
2340:                    ((VersionedNamespaceManager) namespaceManager).uncheckout();
2341:                    setStatusCode(WebDAVStatus.SC_OK);
2342:                } else {
2343:                    throw new WebDAVException(
2344:                            WebDAVStatus.SC_METHOD_NOT_ALLOWED,
2345:                            "Repository does not support this method");
2346:                }
2347:
2348:            }
2349:
2350:            /**
2351:             * 
2352:             */
2353:            public void versionControl() throws WebDAVException {
2354:                if (namespaceManager instanceof  VersionedNamespaceManager) {
2355:                    //			validate the uri
2356:                    if (hasValidURI() == false) {
2357:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2358:                                "Invalid URI");
2359:                    }
2360:
2361:                    // make sure the resource exists
2362:                    if (exists() == false) {
2363:                        throw new WebDAVException(WebDAVStatus.SC_NOT_FOUND,
2364:                                "Cannot copy a lock-null resource");
2365:                    }
2366:
2367:                    if (((VersionedNamespaceManager) namespaceManager)
2368:                            .isVersioned() == true) {
2369:                        throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
2370:                                "Already versioned");
2371:                    }
2372:
2373:                    ((VersionedNamespaceManager) namespaceManager)
2374:                            .versionControl();
2375:                    setStatusCode(WebDAVStatus.SC_OK);
2376:                } else {
2377:                    throw new WebDAVException(
2378:                            WebDAVStatus.SC_METHOD_NOT_ALLOWED,
2379:                            "Repository does not support this method");
2380:                }
2381:
2382:            }
2383:
2384:            /**
2385:             * @return
2386:             */
2387:            public List getAllowedMethods() throws WebDAVException {
2388:
2389:                return namespaceManager.getAllowedMethods();
2390:            }
2391:
2392:            /* (non-Javadoc)
2393:             * @see com.ibm.webdav.impl.IRResource#closeContentsOutputStream(com.ibm.webdav.ResourceContext, java.lang.String)
2394:             */
2395:            public void closeContentsOutputStream(ResourceContext context,
2396:                    String sContentType) throws WebDAVException {
2397:                this .context = context;
2398:
2399:                if (sContentType == null) {
2400:                    namespaceManager.closeContentsOutputStream();
2401:                } else {
2402:                    namespaceManager.closeContentsOutputStream(sContentType);
2403:                }
2404:
2405:                // update the live properties
2406:                Document propertiesDocument = loadProperties();
2407:                saveProperties(propertiesDocument);
2408:
2409:                // inherit any deep locks on the parent collection
2410:                inheritParentDeepLocks();
2411:
2412:            }
2413:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.