Source Code Cross Referenced for WebDAVSource.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » components » source » 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 » apache lenya 2.0 » org.apache.cocoon.components.source.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.cocoon.components.source.impl;
0018:
0019:        import java.io.BufferedInputStream;
0020:        import java.io.ByteArrayInputStream;
0021:        import java.io.ByteArrayOutputStream;
0022:        import java.io.IOException;
0023:        import java.io.InputStream;
0024:        import java.io.OutputStream;
0025:        import java.util.ArrayList;
0026:        import java.util.Collection;
0027:        import java.util.Enumeration;
0028:        import java.util.Properties;
0029:        import java.util.Vector;
0030:
0031:        import javax.xml.transform.OutputKeys;
0032:        import javax.xml.transform.TransformerFactory;
0033:        import javax.xml.transform.sax.SAXTransformerFactory;
0034:        import javax.xml.transform.sax.TransformerHandler;
0035:        import javax.xml.transform.stream.StreamResult;
0036:
0037:        import org.apache.avalon.framework.logger.AbstractLogEnabled;
0038:        import org.apache.avalon.framework.logger.Logger;
0039:        import org.apache.cocoon.caching.validity.EventValidity;
0040:        import org.apache.cocoon.components.source.InspectableSource;
0041:        import org.apache.cocoon.components.source.helpers.SourceProperty;
0042:        import org.apache.cocoon.components.webdav.WebDAVEventFactory;
0043:        import org.apache.cocoon.xml.XMLUtils;
0044:        import org.apache.commons.httpclient.HttpException;
0045:        import org.apache.commons.httpclient.HttpStatus;
0046:        import org.apache.commons.httpclient.HttpURL;
0047:        import org.apache.commons.httpclient.HttpsURL;
0048:        import org.apache.commons.httpclient.URIException;
0049:        import org.apache.excalibur.source.ModifiableSource;
0050:        import org.apache.excalibur.source.ModifiableTraversableSource;
0051:        import org.apache.excalibur.source.MoveableSource;
0052:        import org.apache.excalibur.source.Source;
0053:        import org.apache.excalibur.source.SourceException;
0054:        import org.apache.excalibur.source.SourceNotFoundException;
0055:        import org.apache.excalibur.source.SourceParameters;
0056:        import org.apache.excalibur.source.SourceUtil;
0057:        import org.apache.excalibur.source.SourceValidity;
0058:        import org.apache.excalibur.source.TraversableSource;
0059:        import org.apache.excalibur.source.impl.validity.TimeStampValidity;
0060:        import org.apache.webdav.lib.Property;
0061:        import org.apache.webdav.lib.PropertyName;
0062:        import org.apache.webdav.lib.ResponseEntity;
0063:        import org.apache.webdav.lib.WebdavResource;
0064:        import org.apache.webdav.lib.methods.DepthSupport;
0065:        import org.w3c.dom.Element;
0066:        import org.w3c.dom.Node;
0067:        import org.w3c.dom.NodeList;
0068:        import org.w3c.dom.Text;
0069:        import org.xml.sax.ContentHandler;
0070:        import org.xml.sax.SAXException;
0071:        import org.xml.sax.helpers.AttributesImpl;
0072:
0073:        /**
0074:         * A source implementation to get access to WebDAV repositories.
0075:         *
0076:         * <h2>Protocol syntax</h2>
0077:         * <p><code>webdav://[user[:password]@]host[:port][/path][?cocoon:webdav-depth][&cocoon:webdav-action]</code></p>
0078:         * <p>
0079:         *  <ul>
0080:         *   <li>
0081:         *    <code>cocoon:webdav-depth</code> allows to specify the default depth
0082:         *    to use during initialization of the webdav resource.
0083:         *   </li>
0084:         *   <li>
0085:         *    <code>cocoon:webdav-action</code> allows to specify a default action
0086:         *    to take upon initialization of the webdav resource.
0087:         *   </li>
0088:         *  </ul>
0089:         * <p>
0090:         *
0091:         * @version $Id: WebDAVSource.java 479296 2006-11-26 06:28:51Z antonio $
0092:         */
0093:        public class WebDAVSource extends AbstractLogEnabled implements  Source,
0094:                TraversableSource, ModifiableSource,
0095:                ModifiableTraversableSource, InspectableSource, MoveableSource {
0096:
0097:            private static final String NAMESPACE = "http://apache.org/cocoon/webdav/1.0";
0098:
0099:            private static final String PREFIX = "webdav";
0100:            private static final String RESOURCE_NAME = "resource";
0101:            private static final String COLLECTION_NAME = "collection";
0102:
0103:            // the http url
0104:            private final HttpURL url;
0105:
0106:            // the scheme name
0107:            private final String protocol;
0108:
0109:            // cached uri and secureUri values
0110:            private String uri;
0111:            private String secureUri;
0112:
0113:            // the event factory to get the Event objects from for event caching
0114:            private WebDAVEventFactory eventfactory = null;
0115:
0116:            // the SWCL resource
0117:            private WebdavResource resource = null;
0118:
0119:            // current resource initialization values
0120:            private int depth = -1;
0121:            private int action = -1;
0122:
0123:            /**
0124:             * Default constructor.
0125:             */
0126:            private WebDAVSource(HttpURL url, String protocol)
0127:                    throws URIException {
0128:                this .protocol = protocol;
0129:                this .url = url;
0130:
0131:                String qs = url.getQuery();
0132:                if (qs != null) {
0133:                    final SourceParameters sp = new SourceParameters(qs);
0134:
0135:                    // parse optional start depth and start action qs parameters
0136:                    this .depth = sp.getParameterAsInteger(
0137:                            "cocoon:webdav-depth", DepthSupport.DEPTH_1);
0138:                    this .action = sp.getParameterAsInteger(
0139:                            "cocoon:webdav-action", WebdavResource.NOACTION);
0140:
0141:                    // [UH] FIXME: Why this alternative way of passing in credentials?
0142:                    String principal = url.getUser();
0143:                    String password = url.getPassword();
0144:                    if (principal == null || password == null) {
0145:                        principal = sp.getParameter("cocoon:webdav-principal",
0146:                                principal);
0147:                        password = sp.getParameter("cocoon:webdav-password",
0148:                                password);
0149:                        if (principal != null) {
0150:                            url.setUser(principal);
0151:                            url.setPassword(password);
0152:                        }
0153:                    }
0154:
0155:                    sp.removeParameter("cocoon:webdav-depth");
0156:                    sp.removeParameter("cocoon:webdav-action");
0157:                    sp.removeParameter("cocoon:webdav-principal");
0158:                    sp.removeParameter("cocoon:webdav-password");
0159:
0160:                    // set the qs without WebdavSource specific parameters
0161:                    url.setQuery(sp.getQueryString());
0162:                }
0163:            }
0164:
0165:            /**
0166:             * Constructor used by getChildren() method.
0167:             */
0168:            private WebDAVSource(WebdavResource resource, HttpURL url,
0169:                    String protocol) throws URIException {
0170:                this (url, protocol);
0171:                this .resource = resource;
0172:            }
0173:
0174:            private void setWebDAVEventFactory(WebDAVEventFactory factory) {
0175:                eventfactory = factory;
0176:            }
0177:
0178:            /**
0179:             * Initialize the SWCL WebdavResource.
0180:             * <p>
0181:             * The action argument specifies a set of properties to load during initialization.
0182:             * Its value is one of WebdavResource.NOACTION, WebdavResource.NAME,
0183:             * WebdavResource.BASIC, WebdavResource.DEFAULT, WebdavResource.ALL.
0184:             * Similarly the depth argument specifies the depth header of the PROPFIND
0185:             * method that is executed upon initialization.
0186:             * </p>
0187:             * <p>
0188:             * The different methods of this Source implementation call this method to
0189:             * initialize the resource using their minimal action and depth requirements.
0190:             * For instance the WebDAVSource.getMimeType() method requires WebdavResource.BASIC
0191:             * properties and a search depth of 0 is sufficient.
0192:             * </p>
0193:             * <p>
0194:             * However it may be that a later call (eg. WebDAVSource.getChildren()) requires more
0195:             * information. In that case the WebdavResource would have to make another call to the Server.
0196:             * It would be more efficient if previous initialization had been done using depth 1 instead.
0197:             * In order give the user more control over this the WebDAVSource can be passed a minimal
0198:             * action and depth using cocoon:webdav-depth and cocoon:webdav-action query string parameters.
0199:             * By default the mimimum action is WebdavResource.BASIC (which loads all the following basic
0200:             * webdav properties: DAV:displayname, DAV:getcontentlength, DAV:getcontenttype DAV:resourcetype,
0201:             * DAV:getlastmodified and DAV:lockdiscovery). The default minimum depth is 1.
0202:             * </p>
0203:             *
0204:             * @param action  the set of propterties the WebdavResource should load.
0205:             * @param depth  the webdav depth.
0206:             * @throws SourceException
0207:             * @throws SourceNotFoundException
0208:             */
0209:            private void initResource(int action, int depth)
0210:                    throws SourceException, SourceNotFoundException {
0211:                try {
0212:                    boolean update = false;
0213:                    if (action != WebdavResource.NOACTION) {
0214:                        if (action > this .action) {
0215:                            this .action = action;
0216:                            update = true;
0217:                        } else {
0218:                            action = this .action;
0219:                        }
0220:                    }
0221:                    if (depth > this .depth) {
0222:                        this .depth = depth;
0223:                        update = true;
0224:                    } else {
0225:                        depth = this .depth;
0226:                    }
0227:                    if (this .resource == null) {
0228:                        this .resource = new WebdavResource(this .url, action,
0229:                                depth);
0230:                    } else if (update) {
0231:                        this .resource.setProperties(action, depth);
0232:                    }
0233:                    if (this .action > WebdavResource.NOACTION) {
0234:                        if (this .resource.isCollection()) {
0235:                            String path = this .url.getPath();
0236:                            if (path.charAt(path.length() - 1) != '/') {
0237:                                this .url.setPath(path + "/");
0238:                            }
0239:                        }
0240:                    }
0241:                } catch (HttpException e) {
0242:                    if (e.getReasonCode() == HttpStatus.SC_NOT_FOUND) {
0243:                        throw new SourceNotFoundException("Not found: "
0244:                                + getSecureURI(), e);
0245:                    }
0246:                    if (e.getReasonCode() == HttpStatus.SC_BAD_REQUEST) {
0247:                        throw new SourceException(
0248:                                "Server doesn't appear to understand WebDAV: "
0249:                                        + getSecureURI(), e);
0250:                    }
0251:                    final String msg = "Could not initialize webdav resource at "
0252:                            + getSecureURI()
0253:                            + ". Server responded "
0254:                            + e.getReasonCode()
0255:                            + " ("
0256:                            + e.getReason()
0257:                            + ") - "
0258:                            + e.getMessage();
0259:                    throw new SourceException(msg, e);
0260:                } catch (IOException e) {
0261:                    throw new SourceException(
0262:                            "Could not initialize webdav resource", e);
0263:                }
0264:            }
0265:
0266:            /**
0267:             * Static factory method to obtain a Source.
0268:             */
0269:            public static WebDAVSource newWebDAVSource(HttpURL url,
0270:                    String protocol, Logger logger,
0271:                    WebDAVEventFactory eventfactory) throws URIException {
0272:                final WebDAVSource source = new WebDAVSource(url, protocol);
0273:                source.enableLogging(logger);
0274:                source.setWebDAVEventFactory(eventfactory);
0275:                return source;
0276:            }
0277:
0278:            /**
0279:             * Static factory method to obtain a Source.
0280:             */
0281:            private static WebDAVSource newWebDAVSource(
0282:                    WebdavResource resource, HttpURL url, String protocol,
0283:                    Logger logger, WebDAVEventFactory eventfactory)
0284:                    throws URIException {
0285:                final WebDAVSource source = new WebDAVSource(resource, url,
0286:                        protocol);
0287:                source.enableLogging(logger);
0288:                source.setWebDAVEventFactory(eventfactory);
0289:                return source;
0290:            }
0291:
0292:            // ---------------------------------------------------- Source implementation
0293:
0294:            /**
0295:             * Get the scheme for this Source.
0296:             */
0297:            public String getScheme() {
0298:                return this .protocol;
0299:            }
0300:
0301:            /**
0302:             * Return the unique identifer for this source
0303:             */
0304:            public String getURI() {
0305:                if (this .uri == null) {
0306:                    String uri = this .url.toString();
0307:                    final int index = uri.indexOf("://");
0308:                    if (index != -1) {
0309:                        uri = uri.substring(index + 3);
0310:                    }
0311:                    final String userinfo = this .url.getEscapedUserinfo();
0312:                    if (userinfo != null) {
0313:                        uri = this .protocol + "://" + userinfo + "@" + uri;
0314:                    } else {
0315:                        uri = this .protocol + "://" + uri;
0316:                    }
0317:                    this .uri = uri;
0318:                }
0319:                return this .uri;
0320:            }
0321:
0322:            /**
0323:             * Return the URI securely, without username and password
0324:             */
0325:            protected String getSecureURI() {
0326:                if (this .secureUri == null) {
0327:                    String uri = this .url.toString();
0328:                    int index = uri.indexOf("://");
0329:                    if (index != -1) {
0330:                        uri = uri.substring(index + 3);
0331:                    }
0332:                    uri = this .protocol + "://" + uri;
0333:                    this .secureUri = uri;
0334:                }
0335:                return this .secureUri;
0336:            }
0337:
0338:            /**
0339:             *  Get the Validity object. This can either wrap the last modification
0340:             *  date or the expires information or...
0341:             *  If it is currently not possible to calculate such an information
0342:             *  <code>null</code> is returned.
0343:             */
0344:            public SourceValidity getValidity() {
0345:
0346:                SourceValidity validity = null;
0347:
0348:                if (eventfactory != null) {
0349:                    try {
0350:                        validity = new EventValidity(eventfactory
0351:                                .createEvent(this .url));
0352:
0353:                        if (getLogger().isDebugEnabled())
0354:                            getLogger().debug(
0355:                                    "Created EventValidity for source: "
0356:                                            + validity);
0357:
0358:                    } catch (Exception e) {
0359:                        if (getLogger().isErrorEnabled())
0360:                            getLogger().error(
0361:                                    "could not create EventValidity!", e);
0362:                    }
0363:                }
0364:
0365:                if (validity == null) {
0366:                    if (getLogger().isDebugEnabled())
0367:                        getLogger().debug("Falling back to TimeStampValidity!");
0368:
0369:                    final long lm = getLastModified();
0370:                    if (lm > 0) {
0371:                        validity = new TimeStampValidity(lm);
0372:                    }
0373:                }
0374:
0375:                return validity;
0376:            }
0377:
0378:            /**
0379:             * Refresh the content of this object after the underlying data
0380:             * content has changed.
0381:             */
0382:            public void refresh() {
0383:                this .resource = null;
0384:            }
0385:
0386:            /**
0387:             * Return an <code>InputStream</code> object to read from the source.
0388:             * This is the data at the point of invocation of this method,
0389:             * so if this is Modifiable, you might get different content
0390:             * from two different invocations.
0391:             */
0392:            public InputStream getInputStream() throws IOException,
0393:                    SourceException {
0394:                initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
0395:                try {
0396:                    if (this .resource.isCollection()) {
0397:                        // [UH] FIXME: why list collection as XML here?
0398:                        // I think its a concern for the TraversableGenerator.
0399:                        WebdavResource[] resources = this .resource
0400:                                .listWebdavResources();
0401:                        return resourcesToXml(resources);
0402:                    } else {
0403:                        BufferedInputStream bi = null;
0404:                        bi = new BufferedInputStream(this .resource
0405:                                .getMethodData());
0406:                        if (!this .resource.exists()) {
0407:                            throw new HttpException(getSecureURI()
0408:                                    + " does not exist");
0409:                        }
0410:                        return bi;
0411:                    }
0412:                } catch (HttpException he) {
0413:                    throw new SourceException("Could not get WebDAV resource "
0414:                            + getSecureURI(), he);
0415:                } catch (Exception e) {
0416:                    throw new SourceException("Could not get WebDAV resource"
0417:                            + getSecureURI(), e);
0418:                }
0419:            }
0420:
0421:            /**
0422:             * The mime-type of the content described by this object.
0423:             * If the source is not able to determine the mime-type by itself
0424:             * this can be <code>null</code>.
0425:             */
0426:            public String getMimeType() {
0427:                try {
0428:                    initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
0429:                } catch (IOException e) {
0430:                    return null;
0431:                }
0432:                return this .resource.getGetContentType();
0433:            }
0434:
0435:            /**
0436:             * Return the content length of the content or -1 if the length is
0437:             * unknown
0438:             */
0439:            public long getContentLength() {
0440:                try {
0441:                    initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
0442:                } catch (IOException e) {
0443:                    return -1;
0444:                }
0445:                if (this .resource.isCollection()) {
0446:                    return -1;
0447:                }
0448:                return this .resource.getGetContentLength();
0449:            }
0450:
0451:            /**
0452:             * Get the last modification date.
0453:             * @return The last modification in milliseconds since January 1, 1970 GMT
0454:             *         or 0 if it is unknown
0455:             */
0456:            public long getLastModified() {
0457:                try {
0458:                    initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
0459:                } catch (IOException e) {
0460:                    return 0;
0461:                }
0462:                return this .resource.getGetLastModified();
0463:            }
0464:
0465:            /**
0466:             * Does this source actually exist ?
0467:             *
0468:             * @return true if the resource exists.
0469:             */
0470:            public boolean exists() {
0471:                try {
0472:                    initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
0473:                } catch (SourceNotFoundException e) {
0474:                    return false;
0475:                } catch (IOException e) {
0476:                    return true;
0477:                }
0478:                return this .resource.getExistence();
0479:            }
0480:
0481:            private InputStream resourcesToXml(WebdavResource[] resources)
0482:                    throws Exception {
0483:                TransformerFactory tf = TransformerFactory.newInstance();
0484:                TransformerHandler th = ((SAXTransformerFactory) tf)
0485:                        .newTransformerHandler();
0486:                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0487:                StreamResult result = new StreamResult(bOut);
0488:                th.setResult(result);
0489:                th.startDocument();
0490:                th.startPrefixMapping(PREFIX, NAMESPACE);
0491:                th.startElement(NAMESPACE, COLLECTION_NAME, PREFIX + ":"
0492:                        + COLLECTION_NAME, XMLUtils.EMPTY_ATTRIBUTES);
0493:                resourcesToSax(resources, th);
0494:                th.endElement(NAMESPACE, COLLECTION_NAME, PREFIX + ":"
0495:                        + COLLECTION_NAME);
0496:                th.endPrefixMapping(PREFIX);
0497:                th.endDocument();
0498:
0499:                return new ByteArrayInputStream(bOut.toByteArray());
0500:            }
0501:
0502:            private void resourcesToSax(WebdavResource[] resources,
0503:                    ContentHandler handler) throws SAXException {
0504:                for (int i = 0; i < resources.length; i++) {
0505:                    if (getLogger().isDebugEnabled()) {
0506:                        final String message = "RESOURCE: "
0507:                                + resources[i].getDisplayName();
0508:                        getLogger().debug(message);
0509:                    }
0510:                    if (resources[i].isCollection()) {
0511:                        try {
0512:                            WebdavResource[] childs = resources[i]
0513:                                    .listWebdavResources();
0514:                            AttributesImpl attrs = new AttributesImpl();
0515:                            attrs.addAttribute(NAMESPACE, COLLECTION_NAME,
0516:                                    PREFIX + ":name", "CDATA", resources[i]
0517:                                            .getDisplayName());
0518:                            handler.startElement(NAMESPACE, COLLECTION_NAME,
0519:                                    PREFIX + ":" + COLLECTION_NAME, attrs);
0520:                            this .resourcesToSax(childs, handler);
0521:                            handler.endElement(NAMESPACE, COLLECTION_NAME,
0522:                                    PREFIX + ":" + COLLECTION_NAME);
0523:                        } catch (HttpException e) {
0524:                            if (getLogger().isDebugEnabled()) {
0525:                                final String message = "Unable to get WebDAV children. Server responded "
0526:                                        + e.getReasonCode()
0527:                                        + " ("
0528:                                        + e.getReason()
0529:                                        + ") - "
0530:                                        + e.getMessage();
0531:                                getLogger().debug(message);
0532:                            }
0533:                        } catch (SAXException e) {
0534:                            if (getLogger().isDebugEnabled()) {
0535:                                final String message = "Unable to get WebDAV children: "
0536:                                        + e.getMessage();
0537:                                getLogger().debug(message, e);
0538:                            }
0539:                        } catch (IOException e) {
0540:                            if (getLogger().isDebugEnabled()) {
0541:                                final String message = "Unable to get WebDAV children: "
0542:                                        + e.getMessage();
0543:                                getLogger().debug(message, e);
0544:                            }
0545:                        } catch (Exception e) {
0546:                            if (getLogger().isDebugEnabled()) {
0547:                                final String message = "Unable to get WebDAV children: "
0548:                                        + e.getMessage();
0549:                                getLogger().debug(message, e);
0550:                            }
0551:                        }
0552:                    } else {
0553:                        AttributesImpl attrs = new AttributesImpl();
0554:                        attrs.addAttribute(NAMESPACE, "name", PREFIX + ":name",
0555:                                "CDATA", resources[i].getDisplayName());
0556:                        handler.startElement(NAMESPACE, RESOURCE_NAME, PREFIX
0557:                                + ":" + RESOURCE_NAME, attrs);
0558:                        handler.endElement(NAMESPACE, RESOURCE_NAME, PREFIX
0559:                                + ":" + RESOURCE_NAME);
0560:                    }
0561:                }
0562:            }
0563:
0564:            // ---------------------------------------------------- TraversableSource implementation
0565:
0566:            /**
0567:             * Get a collection child.
0568:             *
0569:             * @see org.apache.excalibur.source.TraversableSource#getChild(java.lang.String)
0570:             */
0571:            public Source getChild(String childName) throws SourceException {
0572:                if (!isCollection()) {
0573:                    throw new SourceException(getSecureURI()
0574:                            + " is not a collection.");
0575:                }
0576:                try {
0577:                    HttpURL childURL;
0578:                    if (this .url instanceof  HttpsURL) {
0579:                        childURL = new HttpsURL((HttpsURL) this .url, childName);
0580:                    } else {
0581:                        childURL = new HttpURL(this .url, childName);
0582:                    }
0583:                    return WebDAVSource.newWebDAVSource(childURL,
0584:                            this .protocol, getLogger(), eventfactory);
0585:                } catch (URIException e) {
0586:                    throw new SourceException("Failed to create child", e);
0587:                }
0588:            }
0589:
0590:            /**
0591:             * Get the collection children.
0592:             *
0593:             * @see org.apache.excalibur.source.TraversableSource#getChildren()
0594:             */
0595:            public Collection getChildren() throws SourceException {
0596:                initResource(WebdavResource.BASIC, DepthSupport.DEPTH_1);
0597:                ArrayList children = new ArrayList();
0598:                try {
0599:                    WebdavResource[] resources = this .resource
0600:                            .listWebdavResources();
0601:                    for (int i = 0; i < resources.length; i++) {
0602:                        HttpURL childURL;
0603:                        if (this .url instanceof  HttpsURL) {
0604:                            childURL = new HttpsURL((HttpsURL) this .url,
0605:                                    resources[i].getName());
0606:                        } else {
0607:                            childURL = new HttpURL(this .url, resources[i]
0608:                                    .getName());
0609:                        }
0610:                        WebDAVSource src = WebDAVSource.newWebDAVSource(
0611:                                resources[i], childURL, this .protocol,
0612:                                getLogger(), this .eventfactory);
0613:                        src.enableLogging(getLogger());
0614:                        children.add(src);
0615:                    }
0616:                } catch (HttpException e) {
0617:                    if (getLogger().isDebugEnabled()) {
0618:                        final String message = "Unable to get WebDAV children. Server responded "
0619:                                + e.getReasonCode()
0620:                                + " ("
0621:                                + e.getReason()
0622:                                + ") - " + e.getMessage();
0623:                        getLogger().debug(message);
0624:                    }
0625:                    throw new SourceException(
0626:                            "Failed to get WebDAV collection children.", e);
0627:                } catch (SourceException e) {
0628:                    throw e;
0629:                } catch (IOException e) {
0630:                    throw new SourceException(
0631:                            "Failed to get WebDAV collection children.", e);
0632:                }
0633:                return children;
0634:            }
0635:
0636:            /**
0637:             * Get the name of this resource.
0638:             * @see org.apache.excalibur.source.TraversableSource#getName()
0639:             */
0640:            public String getName() {
0641:                try {
0642:                    initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0643:                } catch (IOException e) {
0644:                    return "";
0645:                }
0646:                return this .resource.getName();
0647:            }
0648:
0649:            /**
0650:             * Get the parent.
0651:             *
0652:             * @see org.apache.excalibur.source.TraversableSource#getParent()
0653:             */
0654:            public Source getParent() throws SourceException {
0655:                String path;
0656:                if (this .url.getEscapedPath().endsWith("/")) {
0657:                    path = "..";
0658:                } else {
0659:                    path = ".";
0660:                }
0661:                try {
0662:                    HttpURL parentURL;
0663:                    if (url instanceof  HttpsURL) {
0664:                        parentURL = new HttpsURL((HttpsURL) this .url, path);
0665:                    } else {
0666:                        parentURL = new HttpURL(this .url, path);
0667:                    }
0668:                    return WebDAVSource.newWebDAVSource(parentURL,
0669:                            this .protocol, getLogger(), eventfactory);
0670:                } catch (URIException e) {
0671:                    throw new SourceException("Failed to create parent", e);
0672:                }
0673:            }
0674:
0675:            /**
0676:             * Check if this source is a collection.
0677:             * @see org.apache.excalibur.source.TraversableSource#isCollection()
0678:             */
0679:            public boolean isCollection() {
0680:                try {
0681:                    initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
0682:                } catch (IOException e) {
0683:                    return false;
0684:                }
0685:                return this .resource.isCollection();
0686:            }
0687:
0688:            // ---------------------------------------------------- ModifiableSource implementation
0689:
0690:            /**
0691:             * Get an <code>OutputStream</code> where raw bytes can be written to.
0692:             * The signification of these bytes is implementation-dependent and
0693:             * is not restricted to a serialized XML document.
0694:             *
0695:             * @return a stream to write to
0696:             */
0697:            public OutputStream getOutputStream() throws IOException {
0698:                return new WebDAVSourceOutputStream(this );
0699:            }
0700:
0701:            /**
0702:             * Can the data sent to an <code>OutputStream</code> returned by
0703:             * {@link #getOutputStream()} be cancelled ?
0704:             *
0705:             * @return true if the stream can be cancelled
0706:             */
0707:            public boolean canCancel(OutputStream stream) {
0708:                if (stream instanceof  WebDAVSourceOutputStream) {
0709:                    WebDAVSourceOutputStream wsos = (WebDAVSourceOutputStream) stream;
0710:                    if (wsos.source == this ) {
0711:                        return wsos.canCancel();
0712:                    }
0713:                }
0714:                throw new IllegalArgumentException(
0715:                        "The stream is not associated to this source");
0716:            }
0717:
0718:            /**
0719:             * Cancel the data sent to an <code>OutputStream</code> returned by
0720:             * {@link #getOutputStream()}.
0721:             * <p>
0722:             * After cancel, the stream should no more be used.
0723:             */
0724:            public void cancel(OutputStream stream) throws SourceException {
0725:                if (stream instanceof  WebDAVSourceOutputStream) {
0726:                    WebDAVSourceOutputStream wsos = (WebDAVSourceOutputStream) stream;
0727:                    if (wsos.source == this ) {
0728:                        try {
0729:                            wsos.cancel();
0730:                        } catch (Exception e) {
0731:                            throw new SourceException(
0732:                                    "Failure cancelling Source", e);
0733:                        }
0734:                    }
0735:                }
0736:                throw new IllegalArgumentException(
0737:                        "The stream is not associated to this source");
0738:            }
0739:
0740:            /**
0741:             * Delete this source (unimplemented).
0742:             * @see org.apache.excalibur.source.ModifiableSource#delete()
0743:             */
0744:            public void delete() throws SourceException {
0745:                initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0746:                try {
0747:                    this .resource.deleteMethod();
0748:                } catch (HttpException e) {
0749:                    throw new SourceException("Unable to delete source: "
0750:                            + getSecureURI(), e);
0751:                } catch (IOException e) {
0752:                    throw new SourceException("Unable to delete source: "
0753:                            + getSecureURI(), e);
0754:                }
0755:            }
0756:
0757:            private static class WebDAVSourceOutputStream extends
0758:                    ByteArrayOutputStream {
0759:
0760:                private WebDAVSource source = null;
0761:                private boolean isClosed = false;
0762:
0763:                private WebDAVSourceOutputStream(WebDAVSource source) {
0764:                    this .source = source;
0765:                }
0766:
0767:                public void close() throws IOException {
0768:                    if (!isClosed) {
0769:                        try {
0770:                            super .close();
0771:                            this .source.initResource(WebdavResource.NOACTION,
0772:                                    DepthSupport.DEPTH_0);
0773:                            this .source.resource.putMethod(toByteArray());
0774:                        } catch (HttpException he) {
0775:                            final String message = "Unable to close output stream. Server responded "
0776:                                    + he.getReasonCode()
0777:                                    + " ("
0778:                                    + he.getReason() + ") - " + he.getMessage();
0779:                            this .source.getLogger().debug(message);
0780:                            throw new IOException(he.getMessage());
0781:                        } finally {
0782:                            this .isClosed = true;
0783:                        }
0784:                    }
0785:                }
0786:
0787:                private boolean canCancel() {
0788:                    return !isClosed;
0789:                }
0790:
0791:                private void cancel() {
0792:                    if (isClosed) {
0793:                        throw new IllegalStateException(
0794:                                "Cannot cancel: outputstream is already closed");
0795:                    }
0796:                    this .isClosed = true;
0797:                }
0798:            }
0799:
0800:            // ---------------------------------------------------- ModifiableTraversableSource implementation
0801:
0802:            /**
0803:             * Create the collection, if it doesn't exist.
0804:             * @see org.apache.excalibur.source.ModifiableTraversableSource#makeCollection()
0805:             */
0806:            public void makeCollection() throws SourceException {
0807:                initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0808:                if (this .resource.exists())
0809:                    return;
0810:                try {
0811:                    if (!this .resource.mkcolMethod()) {
0812:                        int status = this .resource.getStatusCode();
0813:                        if (status == 409) {
0814:                            // parent does not exist, create it and try again
0815:                            ((ModifiableTraversableSource) getParent())
0816:                                    .makeCollection();
0817:                            makeCollection();
0818:                        } else if (status == 404) {
0819:                            // apparently mod_dav_svn wrongly returns 404
0820:                            // on MKCOL when parent does not exist
0821:                            ((ModifiableTraversableSource) getParent())
0822:                                    .makeCollection();
0823:                            makeCollection();
0824:                        }
0825:                        // Ignore status 405 - Not allowed: collection already exists
0826:                        else if (status != 405) {
0827:                            final String msg = "Unable to create collection "
0828:                                    + getSecureURI() + ". Server responded "
0829:                                    + this .resource.getStatusCode() + " ("
0830:                                    + this .resource.getStatusMessage() + ")";
0831:                            throw new SourceException(msg);
0832:                        }
0833:                    }
0834:                } catch (HttpException e) {
0835:                    throw new SourceException("Unable to create collection(s) "
0836:                            + getSecureURI(), e);
0837:                } catch (SourceException e) {
0838:                    throw e;
0839:                } catch (IOException e) {
0840:                    throw new SourceException("Unable to create collection(s)"
0841:                            + getSecureURI(), e);
0842:                }
0843:            }
0844:
0845:            // ---------------------------------------------------- InspectableSource implementation
0846:
0847:            /**
0848:             * Returns a enumeration of the properties
0849:             *
0850:             * @return Enumeration of SourceProperty
0851:             *
0852:             * @throws SourceException If an exception occurs.
0853:             */
0854:            public SourceProperty[] getSourceProperties()
0855:                    throws SourceException {
0856:
0857:                initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0858:
0859:                Vector sourceproperties = new Vector();
0860:                Enumeration props = null;
0861:                org.apache.webdav.lib.Property prop = null;
0862:
0863:                try {
0864:                    Enumeration responses = this .resource.propfindMethod(0);
0865:                    while (responses.hasMoreElements()) {
0866:
0867:                        ResponseEntity response = (ResponseEntity) responses
0868:                                .nextElement();
0869:                        props = response.getProperties();
0870:                        while (props.hasMoreElements()) {
0871:                            prop = (Property) props.nextElement();
0872:                            SourceProperty srcProperty = new SourceProperty(
0873:                                    prop.getElement());
0874:                            sourceproperties.addElement(srcProperty);
0875:                        }
0876:                    }
0877:
0878:                } catch (Exception e) {
0879:                    throw new SourceException("Error getting properties", e);
0880:                }
0881:                SourceProperty[] sourcepropertiesArray = new SourceProperty[sourceproperties
0882:                        .size()];
0883:                for (int i = 0; i < sourceproperties.size(); i++) {
0884:                    sourcepropertiesArray[i] = (SourceProperty) sourceproperties
0885:                            .elementAt(i);
0886:                }
0887:                return sourcepropertiesArray;
0888:            }
0889:
0890:            /**
0891:             * Returns a property from a source.
0892:             *
0893:             * @param namespace Namespace of the property
0894:             * @param name Name of the property
0895:             *
0896:             * @return Property of the source.
0897:             *
0898:             * @throws SourceException If an exception occurs.
0899:             */
0900:            public SourceProperty getSourceProperty(String namespace,
0901:                    String name) throws SourceException {
0902:
0903:                initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0904:
0905:                Vector propNames = new Vector(1);
0906:                propNames.add(new PropertyName(namespace, name));
0907:                Enumeration props = null;
0908:                org.apache.webdav.lib.Property prop = null;
0909:                try {
0910:                    Enumeration responses = this .resource.propfindMethod(0,
0911:                            propNames);
0912:                    while (responses.hasMoreElements()) {
0913:                        ResponseEntity response = (ResponseEntity) responses
0914:                                .nextElement();
0915:                        props = response.getProperties();
0916:                        if (props.hasMoreElements()) {
0917:                            prop = (Property) props.nextElement();
0918:                            return new SourceProperty(prop.getElement());
0919:                        }
0920:                    }
0921:                } catch (Exception e) {
0922:                    throw new SourceException(
0923:                            "Error getting property: " + name, e);
0924:                }
0925:                return null;
0926:            }
0927:
0928:            /**
0929:             * Remove a specified source property.
0930:             *
0931:             * @param namespace Namespace of the property.
0932:             * @param name Name of the property.
0933:             *
0934:             * @throws SourceException If an exception occurs.
0935:             */
0936:            public void removeSourceProperty(String namespace, String name)
0937:                    throws SourceException {
0938:
0939:                initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0940:
0941:                try {
0942:                    this .resource.proppatchMethod(new PropertyName(namespace,
0943:                            name), "", false);
0944:                } catch (Exception e) {
0945:                    throw new SourceException("Could not remove property ", e);
0946:                }
0947:            }
0948:
0949:            /**
0950:             * Sets a property for a source.
0951:             *
0952:             * @param sourceproperty Property of the source
0953:             *
0954:             * @throws SourceException If an exception occurs during this operation
0955:             */
0956:            public void setSourceProperty(SourceProperty sourceproperty)
0957:                    throws SourceException {
0958:
0959:                initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
0960:
0961:                try {
0962:                    Node node = null;
0963:                    NodeList list = sourceproperty.getValue().getChildNodes();
0964:                    for (int i = 0; i < list.getLength(); i++) {
0965:                        if ((list.item(i) instanceof  Text && !"".equals(list
0966:                                .item(i).getNodeValue()))
0967:                                || list.item(i) instanceof  Element) {
0968:
0969:                            node = list.item(i);
0970:                            break;
0971:                        }
0972:                    }
0973:
0974:                    Properties format = new Properties();
0975:                    format.put(OutputKeys.METHOD, "xml");
0976:                    format.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
0977:                    String prop = XMLUtils.serializeNode(node, format);
0978:
0979:                    this .resource.proppatchMethod(new PropertyName(
0980:                            sourceproperty.getNamespace(), sourceproperty
0981:                                    .getName()), prop, true);
0982:
0983:                } catch (HttpException e) {
0984:                    final String message = "Unable to set property. Server responded "
0985:                            + e.getReasonCode()
0986:                            + " ("
0987:                            + e.getReason()
0988:                            + ") - "
0989:                            + e.getMessage();
0990:                    getLogger().debug(message);
0991:                    throw new SourceException("Could not set property ", e);
0992:                } catch (Exception e) {
0993:                    throw new SourceException("Could not set property ", e);
0994:                }
0995:            }
0996:
0997:            /**
0998:             * Get the current credential for the source
0999:             */
1000:            //    public SourceCredential getSourceCredential() throws SourceException {
1001:            //        if (this.principal != null) {
1002:            //            return new SourceCredential(this.principal, this.password);
1003:            //        }
1004:            //        return null;
1005:            //    }
1006:            /**
1007:             * Set the credential for the source
1008:             */
1009:            //    public void setSourceCredential(SourceCredential sourcecredential)
1010:            //        throws SourceException {
1011:            //        if (sourcecredential != null) {
1012:            //            this.password = sourcecredential.getPassword();
1013:            //            this.principal = sourcecredential.getPrincipal();
1014:            //            refresh();
1015:            //        }
1016:            //    }
1017:            // ---------------------------------------------------- MoveableSource
1018:            /**
1019:             * Move the current source to a specified destination.
1020:             *
1021:             * @param source
1022:             *
1023:             * @throws SourceException If an exception occurs during the move.
1024:             */
1025:            public void moveTo(Source source) throws SourceException {
1026:                if (source instanceof  WebDAVSource) {
1027:                    initResource(WebdavResource.NOACTION, DepthSupport.DEPTH_0);
1028:                    WebDAVSource destination = (WebDAVSource) source;
1029:                    destination.initResource(WebdavResource.BASIC,
1030:                            DepthSupport.DEPTH_0);
1031:                    try {
1032:                        this .resource.moveMethod(destination.resource
1033:                                .getHttpURL().getPath());
1034:                    } catch (HttpException e) {
1035:                        throw new SourceException("Cannot move source '"
1036:                                + getSecureURI() + "'", e);
1037:                    } catch (IOException e) {
1038:                        throw new SourceException("Cannot move source '"
1039:                                + getSecureURI() + "'", e);
1040:                    }
1041:                } else {
1042:                    SourceUtil.move(this , source);
1043:                }
1044:            }
1045:
1046:            /**
1047:             * Copy the current source to a specified destination.
1048:             *
1049:             * @param source
1050:             *
1051:             * @throws SourceException If an exception occurs during the copy.
1052:             */
1053:            public void copyTo(Source source) throws SourceException {
1054:                if (source instanceof  WebDAVSource) {
1055:                    initResource(WebdavResource.BASIC, DepthSupport.DEPTH_0);
1056:                    WebDAVSource destination = (WebDAVSource) source;
1057:                    destination.initResource(WebdavResource.NOACTION,
1058:                            DepthSupport.DEPTH_0);
1059:                    try {
1060:                        this .resource.copyMethod(destination.resource
1061:                                .getHttpURL().getPath());
1062:                    } catch (HttpException e) {
1063:                        throw new SourceException("Cannot copy source '"
1064:                                + getSecureURI() + "'", e);
1065:                    } catch (IOException e) {
1066:                        throw new SourceException("Cannot copy source '"
1067:                                + getSecureURI() + "'", e);
1068:                    }
1069:                } else {
1070:                    SourceUtil.copy(this, source);
1071:                }
1072:            }
1073:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.