Index: src/java/org/apache/lenya/cms/repository/Node.java =================================================================== --- src/java/org/apache/lenya/cms/repository/Node.java (Revision 387571) +++ src/java/org/apache/lenya/cms/repository/Node.java (Arbeitskopie) @@ -135,10 +135,11 @@ boolean isCheckedOut() throws RepositoryException; /** - * @return if the node is checked out by the current user. - * @throws RepositoryException if an error occurs. + * Get identity of user who checked out the node. + * @return Identity of user who checked out the node. + * @throws RepositoryException */ - boolean isCheckedOutByUser() throws RepositoryException; + String checkedOutBy() throws RepositoryException; /** * @return if the node is locked. Index: src/java/org/apache/lenya/cms/repository/SourceNode.java =================================================================== --- src/java/org/apache/lenya/cms/repository/SourceNode.java (Revision 387571) +++ src/java/org/apache/lenya/cms/repository/SourceNode.java (Arbeitskopie) @@ -37,6 +37,7 @@ import org.apache.lenya.ac.User; import org.apache.lenya.cms.cocoon.source.SourceUtil; import org.apache.lenya.cms.metadata.MetaDataManager; +import org.apache.lenya.cms.metadata.dublincore.DublinCore; import org.apache.lenya.cms.publication.DocumentException; import org.apache.lenya.cms.publication.Publication; import org.apache.lenya.cms.publication.PublicationUtil; @@ -165,15 +166,16 @@ } /** - * @see org.apache.lenya.transaction.Transactionable#isCheckedOutByUser() + * @see org.apache.lenya.transaction.Transactionable#checkedOutBy() */ - public boolean isCheckedOutByUser() throws RepositoryException { + public String checkedOutBy() throws RepositoryException { try { - RCMLEntry entry = getRevisionController().getRCML(getRCPath()).getLatestEntry(); - if (entry.getIdentity().equals(getUserId()) && isCheckedOut()) - return true; - else - return false; + if (!isCheckedOut()) { + return null; + } else { + RCMLEntry entry = getRevisionController().getRCML(getRCPath()).getLatestEntry(); + return entry.getIdentity(); + } } catch (Exception e) { throw new RepositoryException(e); } @@ -337,7 +339,7 @@ * @see org.apache.lenya.transaction.Transactionable#lock() */ public void lock() throws RepositoryException { - if (isCheckedOut() && !isCheckedOutByUser()) { + if (isCheckedOut() && getUserId().equals(checkedOutBy())) { throw new RepositoryException("Cannot lock [" + this + "]: node is checked out."); } if (getLogger().isDebugEnabled()) { @@ -612,26 +614,14 @@ * @see org.apache.lenya.cms.repository.Node#getMimeType() */ public String getMimeType() throws RepositoryException { - SourceResolver resolver = null; - Source source = null; try { - resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE); - source = resolver.resolveURI(getRealSourceURI()); - if (source.exists()) { - return source.getMimeType(); - } else { - throw new SourceNotFoundException("The source [" + getRealSourceURI() - + "] does not exist!"); + String mimeType = getMetaDataManager().getDublinCoreMetaData().getFirstValue(DublinCore.ELEMENT_FORMAT); + if (mimeType == null) { + throw new RepositoryException("Mime-type not defined [" + sourceURI + "]"); } - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - if (resolver != null) { - if (source != null) { - resolver.release(source); - } - this.manager.release(resolver); - } + return mimeType; + } catch (DocumentException de) { + throw new RepositoryException("Error getting mime-type [" + sourceURI + "]", de); } } Index: src/java/org/apache/lenya/cms/cocoon/components/modules/input/CustomMetaDataModule.java =================================================================== --- src/java/org/apache/lenya/cms/cocoon/components/modules/input/CustomMetaDataModule.java (Revision 387571) +++ src/java/org/apache/lenya/cms/cocoon/components/modules/input/CustomMetaDataModule.java (Arbeitskopie) @@ -19,86 +19,113 @@ package org.apache.lenya.cms.cocoon.components.modules.input; -import java.util.ArrayList; -import java.util.Iterator; import java.util.Map; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.Serviceable; +import org.apache.cocoon.components.modules.input.AbstractInputModule; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Request; import org.apache.lenya.cms.metadata.MetaData; import org.apache.lenya.cms.publication.Document; import org.apache.lenya.cms.publication.DocumentException; +import org.apache.lenya.cms.publication.DocumentIdentityMap; +import org.apache.lenya.cms.publication.Publication; +import org.apache.lenya.cms.publication.PublicationUtil; +import org.apache.lenya.cms.repository.RepositoryUtil; +import org.apache.lenya.cms.repository.Session; /** * Input module to access custom meta data values. + * {custom-metadata:{attribute-name}:{publication-id}:{area}:{document-language}:{document-id}} */ -public class CustomMetaDataModule extends AbstractPageEnvelopeModule { +public class CustomMetaDataModule extends AbstractInputModule implements Serviceable { + ServiceManager manager; final static String NS_PREFIX = "lenya:"; + /** - * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, - * org.apache.avalon.framework.configuration.Configuration, java.util.Map) + * Parse the parameters and return a document. + * @param parameters + * @param objectModel + * @return The document object created from the parameters + * @throws ConfigurationException */ - public Object getAttribute(String name, Configuration modeConf, Map objectModel) - throws ConfigurationException { - Object value; + protected Document getDocument(String parameters, Map objectModel) + throws ConfigurationException + { + Document document = null; + + Request request = ObjectModelHelper.getRequest(objectModel); + Session session = RepositoryUtil.getSession(request, getLogger()); + DocumentIdentityMap docFactory = new DocumentIdentityMap(session, + this.manager, + getLogger()); - MetaData metaData = getCustomMetaData(objectModel); - - if (!metaData.isValidAttribute(NS_PREFIX + name)) { - throw new ConfigurationException("The attribute [" + name + "] is not supported!"); - } - + // Parse parameters + int start = 0; + int end = parameters.indexOf(":"); + String metadata = parameters.substring(start, end); + start = end+1; + end = parameters.indexOf(":", start+1); + String publicationId = parameters.substring(start, end); + start = end+1; + end = parameters.indexOf(":", start+1); + String area = parameters.substring(start, end); + start = end+1; + end = parameters.indexOf(":", start); + String docLang = parameters.substring(start, end); + start = end+1; + String docId = parameters.substring(start); + try { - value = metaData.getFirstValue(NS_PREFIX + name); - } catch (DocumentException e) { - throw new ConfigurationException("Obtaining custom meta data value for [" + name - + "] failed: ", e); + Publication publication = PublicationUtil.getPublication(this.manager, publicationId); + document = docFactory.get(publication, area, docId, docLang); + } catch (Exception e) { + throw new ConfigurationException("Error getting document with [" + publicationId + ":" + + area + ":" + docId + ":" + docLang + "]: " + e.getMessage(), e); } - - return value; + return document; } - + /** - * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration, - * java.util.Map) + * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, + * org.apache.avalon.framework.configuration.Configuration, java.util.Map) */ - public Iterator getAttributeNames(Configuration modeConf, Map objectModel) - throws ConfigurationException { + public Object getAttribute(String name, Configuration modeConf, Map objectModel) + throws ConfigurationException + { + Object value = null; - // No pre-defined attributes. Return empty iterator. - return new ArrayList().iterator(); - } + Document document = getDocument(name, objectModel); + + String metaDataName = name.substring(0, name.indexOf(":")); + + if (getLogger().isDebugEnabled()) { + getLogger().debug("Document: [" + document.getId() + "]"); + getLogger().debug("metaDataName: [" + metaDataName + "]"); + } - /** - * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, - * org.apache.avalon.framework.configuration.Configuration, java.util.Map) - */ - public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel) - throws ConfigurationException { - Object[] values; - MetaData metaData = getCustomMetaData(objectModel); + MetaData metaData = getCustomMetaData(document); - if (!metaData.isValidAttribute(NS_PREFIX + name)) { - throw new ConfigurationException("The attribute [" + name + "] is not supported!"); + if (!metaData.isValidAttribute(NS_PREFIX + metaDataName)) { + throw new ConfigurationException("The attribute [" + metaDataName + "] is not supported!"); } try { - values = metaData.getValues(NS_PREFIX + name); + value = metaData.getFirstValue(NS_PREFIX + metaDataName); } catch (DocumentException e) { - throw new ConfigurationException("Obtaining custom meta data value for [" + name - + "] failed: ", e); + throw new ConfigurationException("Obtaining custom meta data value for [" + metaDataName + + "] failed: " + e.getMessage(), e); } - return values; + return value; } - protected MetaData getCustomMetaData(Map objectModel) throws ConfigurationException { - // FIXME: There seems to be no reason to pass the attribute name to get the page envelope. - Document document = getEnvelope(objectModel, "").getDocument(); - if (document == null) { - throw new ConfigurationException("There is no document for this page envelope!"); - } + protected MetaData getCustomMetaData(Document document) throws ConfigurationException { MetaData metaData = null; try { metaData = document.getMetaDataManager().getCustomMetaData(); @@ -108,4 +135,8 @@ } return metaData; } + + public void service(ServiceManager manager) throws ServiceException { + this.manager = manager; + } } Index: src/java/org/apache/lenya/cms/usecase/AbstractUsecase.java =================================================================== --- src/java/org/apache/lenya/cms/usecase/AbstractUsecase.java (Revision 387571) +++ src/java/org/apache/lenya/cms/usecase/AbstractUsecase.java (Arbeitskopie) @@ -38,6 +38,7 @@ import org.apache.cocoon.components.ContextHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.servlet.multipart.Part; +import org.apache.lenya.ac.User; import org.apache.lenya.cms.publication.DocumentIdentityMap; import org.apache.lenya.cms.repository.Node; import org.apache.lenya.cms.repository.RepositoryException; @@ -675,10 +676,12 @@ + (objects != null)); try { + String userId = getUserId(); + boolean canExecute = true; for (int i = 0; i < objects.length; i++) { - if (objects[i].isCheckedOut() && !objects[i].isCheckedOutByUser()) { + if (objects[i].isCheckedOut() && userId != null && !userId.equals(objects[i].checkedOutBy())) { if (getLogger().isDebugEnabled()) getLogger().debug("AbstractUsecase::lockInvolvedObjects() can not execute, object [" + objects[i] + "] is already checked out"); @@ -694,7 +697,7 @@ + objects[i]); objects[i].lock(); - if (!isOptimistic() && !objects[i].isCheckedOutByUser()) { + if (!isOptimistic() && userId != null && !userId.equals(objects[i].checkedOutBy())) { objects[i].checkout(); } } @@ -709,6 +712,18 @@ } /** + * Get the id of the current user. + * @return The user id, null if no user exists for current identity. + */ + protected String getUserId() { + User user = getSession().getUnitOfWork().getIdentity().getUser(); + if (user == null) + return null; + else + return user.getId(); + } + + /** * @see org.apache.lenya.cms.usecase.Usecase#cancel() */ public void cancel() throws UsecaseException { Index: src/java/org/apache/lenya/cms/publication/DefaultDocument.java =================================================================== --- src/java/org/apache/lenya/cms/publication/DefaultDocument.java (Revision 387571) +++ src/java/org/apache/lenya/cms/publication/DefaultDocument.java (Arbeitskopie) @@ -32,9 +32,11 @@ import org.apache.lenya.cms.cocoon.source.SourceUtil; import org.apache.lenya.cms.metadata.LenyaMetaData; import org.apache.lenya.cms.metadata.MetaDataManager; +import org.apache.lenya.cms.metadata.dublincore.DublinCore; import org.apache.lenya.cms.publication.util.DocumentVisitor; import org.apache.lenya.cms.repository.Node; import org.apache.lenya.cms.site.SiteManager; +import org.apache.lenya.util.MimeTypeHelper; /** * A typical CMS document. @@ -47,6 +49,9 @@ private DocumentIdentityMap identityMap; protected ServiceManager manager; private MetaDataManager metaDataManager; + + private String extension = null; + private String defaultExtension = "html"; /** * Creates a new instance of DefaultDocument. @@ -190,18 +195,24 @@ return this.identifier.getArea(); } - private String extension = null; - private String defaultExtension = "html"; - /** * @see org.apache.lenya.cms.publication.Document#getExtension() */ public String getExtension() { - if (extension == null) { - getLogger().warn("Default extension will be used: " + defaultExtension); - return defaultExtension; + if (this.extension != null) { + return this.extension; + } else { + try { + String mimeType = getMetaDataManager().getDublinCoreMetaData().getFirstValue(DublinCore.ELEMENT_FORMAT); + String[] ext = MimeTypeHelper.getExtension(mimeType); + if (ext == null) + return defaultExtension; + else + return ext[0]; + } catch (DocumentException e) { + return null; + } } - return this.extension; } /** Index: src/java/org/apache/lenya/cms/publication/DefaultDocumentBuilder.java =================================================================== --- src/java/org/apache/lenya/cms/publication/DefaultDocumentBuilder.java (Revision 387571) +++ src/java/org/apache/lenya/cms/publication/DefaultDocumentBuilder.java (Arbeitskopie) @@ -137,7 +137,7 @@ if (area != null && PublicationImpl.isValidArea(area) && !area.equals(Publication.ADMIN_AREA)) { String documentUrl = info.getDocumentUrl(); - if (documentUrl != null && documentUrl.startsWith("/") && documentUrl.length() > 1) { + if (documentUrl != null && documentUrl.startsWith("/") && !documentUrl.endsWith("/") && documentUrl.length() > 1) { isDocument = true; } } Index: src/java/org/apache/lenya/transaction/Versionable.java =================================================================== --- src/java/org/apache/lenya/transaction/Versionable.java (Revision 387571) +++ src/java/org/apache/lenya/transaction/Versionable.java (Arbeitskopie) @@ -42,10 +42,11 @@ boolean isCheckedOut() throws TransactionException; /** - * @return if the object is checked out by the current user. + * Get identity of user who checked out this versionable. + * @return Identity of user who checked out this versionable, null if not checked-out. * @throws TransactionException if an error occurs. */ - boolean isCheckedOutByUser() throws TransactionException; + String checkedOutBy() throws TransactionException; /** * Checks if the object has been changed since it has been locked. Index: src/java/org/apache/lenya/util/MimeTypeHelper.java =================================================================== --- src/java/org/apache/lenya/util/MimeTypeHelper.java (Revision 0) +++ src/java/org/apache/lenya/util/MimeTypeHelper.java (Revision 0) @@ -0,0 +1,457 @@ +/* + * Copyright 1999-2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.lenya.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * Class for mapping extensions to mime-types vice versa. + */ +public class MimeTypeHelper { + protected static Map mimeType2Extension = null; + protected static Map extension2MimeType = null; + + protected static String[][] MIME_TYPES = { + {"123", "application/vnd.lotus-1-2-3"}, + {"3dm", "x-world/x-3dmf"}, + {"3dmf", "x-world/x-3dmf"}, + {"3gp", "video/3gp"}, + {"3gpp", "audio/3gp"}, + {"aab", "application/x-authorware-bin"}, + {"aam", "application/x-authorware-map"}, + {"aas", "application/x-authorware-map"}, + {"adr", "application/x-msaddr"}, + {"afl", "video/animaflex"}, + {"ai", "application/postscript"}, + {"aif", "audio/x-aiff"}, + {"aifc", "audio/x-aiff"}, + {"aiff", "audio/x-aiff"}, + {"alt", "application/x-up-alert"}, + {"aos", "application/x-nokia-9000-communicator-add-on-software"}, + {"arj", "application/x-arj"}, + {"asc", "text/plain"}, + {"asd", "application/astound"}, + {"asf", "video/x-ms-asf"}, + {"asn", "application/astound"}, + {"asp", "application/x-asap"}, + {"asx", "video/x-ms-asf"}, + {"asz", "application/astound"}, + {"au", "audio/basic"}, + {"avi", "video/avi"}, + {"axs", "application/olescript"}, + {"bas", "text/plain"}, + {"bat", "text/plain"}, + {"bcpio", "application/x-bcpio"}, + {"bin", "application/octet-stream"}, + {"bin", "application/x-macbinary"}, + {"bmp", "image/bmp"}, + {"bmp", "image/x-ms-bmp"}, + {"cacert", "application/x-x509-ca-cert"}, + {"ccs", "text/ccs"}, + {"cdf", "application/x-netcdf"}, + {"cdr", "application/x-cdr"}, + {"cer", "application/x-x509-ca-cert"}, + {"chat", "application/x-chat"}, + {"che", "application/x-up-cacheop"}, + {"cht", "audio/x-dspeech"}, + {"class", "application/octet-stream"}, + {"class", "application/java-class"}, + {"class", "application/x-java-vm"}, + {"class", "application/x-java-applet"}, + {"class", "application/java"}, + {"clp", "image/x-clp"}, + {"cmd", "text/plain"}, + {"cmx", "image/x-cmx"}, + {"cnc", "application/x-cnc"}, + {"cod", "image/cis-cod"}, + {"coda", "application/x-coda"}, + {"com", "application/octet-stream"}, + {"con", "application/x-connector"}, + {"cpi", "image/cpi"}, + {"cpio", "application/x-cpio"}, + {"csh", "application/x-csh"}, + {"csm", "application/x-cu-seeme"}, + {"css", "text/css"}, + {"csv", "text/comma-separated-values"}, + {"cu", "application/x-cu-seeme"}, + {"cut", "image/x-halo-cut"}, + {"dbf", "application/octet-stream"}, + {"dcr", "application/x-director"}, + {"dig", "multipart/mixed"}, + {"dir", "application/x-director"}, + {"doc", "application/msword"}, + {"dsf", "image/x-mgx-dsf"}, + {"dss", "text/dss"}, + {"dst", "application/tajima"}, + {"dus", "audio/x-dspeech"}, + {"dvi", "application/x-dvi"}, + {"dwf", "drawing/x-dwf"}, + {"dwg", "image/vnd"}, + {"dxf", "image/vnd"}, + {"dxr", "application/x-director"}, + {"ebk", "application/x-expandedbook"}, + {"ecert", "application/x-x509-email-cert"}, + {"email", "application/x-x509-email-cert"}, + {"emf", "image/x-emf"}, + {"eps", "application/postscript"}, + {"erf", "application/x-hsp-erf"}, + {"es", "audio/echospeech"}, + {"etf", "image/x-etf"}, + {"etx", "text/x-setext"}, + {"evy", "application/envoy"}, + {"evy", "application/x-envoy"}, + {"exe", "application/x-msdownload"}, + {"exe", "application/octet-stream"}, + {"exe", "application/exe"}, + {"fh4", "image/x-freehand"}, + {"fh5", "image/x-freehand"}, + {"fhc", "image/x-freehand"}, + {"fif", "image/fif"}, + {"fml", "application/fml"}, + {"fpx", "image/x-fpx"}, + {"frl", "application/freeloader"}, + {"fs", "application/X-FSRecipe"}, + {"gif", "image/gif"}, + {"gsd", "audio/gsm"}, + {"gsm", "audio/gsm"}, + {"gtar", "application/x-gtar"}, + {"gz", "application/gzip"}, + {"gz", "application/x-gzip"}, + {"hdf", "application/x-hdf"}, + {"hdml", "text/x-hdml"}, + {"hqx", "application/mac-binhex40"}, + {"htm", "text/html"}, + {"html", "text/html"}, + {"ica", "application/x-ica"}, + {"ief", "image/ief"}, + {"ins", "application/x-NET-Install"}, + {"ips", "application/ips"}, + {"ipx", "application/x-ipix"}, + {"ivr", "i-world/i-vrml"}, + {"jad", "text/vnd.sun.j2me.app-descriptor"}, + {"jar", "application/java-archive"}, + {"jar", "application/x-jar"}, + {"jar.pack.gz", "application/x-java-pack200"}, + {"jardiff", "application/x-java-archive-diff"}, + {"java", "text/x-java-source"}, + {"java", "text/plain"}, + {"jnlp", "application/x-java-jnlp-file"}, + {"jp2", "image/jp2"}, + {"jpe", "image/jpeg"}, + {"jpeg", "image/jpeg"}, + {"jpg", "image/jpeg"}, + {"jpg", "image/pjpeg"}, + {"jps", "image/x-jps"}, + {"js", "application/x-javascript"}, + {"latex", "application/x-latex"}, + {"lha", "application/octet-stream"}, + {"lit", "application/lit"}, + {"lsp", "text/lsp"}, + {"lwp", "application/x-wordpro"}, + {"lzh", "application/octet-stream"}, + {"lzx", "application/octet-stream"}, + {"m3u", "audio/x-mpegurl"}, + {"man", "application/x-troff-man"}, + {"map", "application/x-httpd-imap"}, + {"mbd", "application/mbedlet"}, + {"mcf", "image/vasa"}, + {"mdb", "application/mdb"}, + {"me", "application/x-troff-me"}, + {"mfp", "application/mirage"}, + {"mid", "audio/x-midi"}, + {"midi", "audio/x-midi"}, + {"mif", "application/x-mif"}, + {"mol", "chemical/x-mdl-molfile"}, + {"mov", "video/quicktime"}, + {"movie", "video/x-sgi-movie"}, + {"mp2", "audio/x-mpeg"}, + {"mp3", "audio/mpeg"}, + {"mpe", "video/mpeg"}, + {"mpeg", "video/mpeg"}, + {"mpg", "video/mpeg"}, + {"mpire", "application/x-mpire"}, + {"mpl", "application/x-mpire"}, + {"mpp", "application/vnd.ms-project"}, + {"ms", "application/x-troff-ms"}, + {"msi", "application/msi"}, + {"msi", "application/x-msi"}, + {"msm", "application/msm"}, + {"n2p", "application/n2p"}, + {"nc", "application/x-netcdf"}, + {"npx", "application/x-netfpx"}, + {"nsc", "application/x-nschat"}, + {"oda", "application/oda"}, + {"odt", "application/vnd.oasis.opendocument.text"}, + {"odt", "application/x-vnd.oasis.opendocument.text"}, + {"ofml", "application/fml"}, + {"page", "application/x-coda"}, + {"pbd", "application/vnd.powerbuilder6"}, + {"pbm", "image/x-portable-bitmap"}, + {"pdb", "chemical/x-pdb"}, + {"pdf", "application/pdf"}, + {"pfr", "application/font-tdpfr"}, + {"pgm", "image/x-portable-graymap"}, + {"pgp", "application/x-pgp-plugin"}, + {"pgr", "text/parsnegar-document"}, + {"php", "application/x-httpd-php"}, + {"php3", "application/x-httpd-php3"}, + {"php4", "application/x-httpd-php"}, + {"pls", "application/pls"}, + {"png", "image/png"}, + {"pnm", "image/x-portable-anymap"}, + {"pot", "application/mspowerpoint"}, + {"ppm", "image/x-portable-pixmap"}, + {"pps", "application/mspowerpoint"}, + {"ppt", "application/mspowerpoint"}, + {"ppz", "application/mspowerpoint"}, + {"pqf", "application/x-cprplayer"}, + {"pqi", "application/cprplayer"}, + {"ps", "application/postscript"}, + {"psr", "application/datawindow"}, + {"ptlk", "application/listenup"}, + {"push", "multipart/x-mixed-replace"}, + {"qd3", "x-world/x-3dmf"}, + {"qd3d", "x-world/x-3dmf"}, + {"qrt", "application/quest"}, + {"qt", "video/quicktime"}, + {"qti", "image/x-quicktime"}, + {"qtl", "application/x-quicktimeplayer"}, + {"ra", "audio/x-pn-realaudio"}, + {"ram", "audio/x-pn-realaudio"}, + {"ras", "image/x-cmu-raster"}, + {"rgb", "image/x-rgb"}, + {"rgb", "image/x-rgb"}, + {"rip", "image/rip"}, + {"rm", "audio/x-pn-realaudio"}, + {"rmf", "audio/rmf"}, + {"rmf", "audio/x-rmf"}, + {"rng", "application/ringing-tones"}, + {"roff", "application/x-troff"}, + {"rpm", "audio/x-pn-realaudio-plugin"}, + {"rrf", "application/x-InstallFromTheWeb"}, + {"rss", "application/rss+xml"}, + {"rss", "text/xml"}, + {"rtc", "application/rtc"}, + {"rtf", "application/rtf"}, + {"rtx", "text/richtext"}, + {"sca", "application/x-supercard"}, + {"scert", "application/x-x509-server-cert"}, + {"scr", "application/octet-stream"}, + {"seq", "application/octet-stream-bin"}, + {"ser", "application/x-java-serialized-object"}, + {"sh", "application/x-sh"}, + {"shar", "application/x-shar"}, + {"shtml", "text/x-server-parsed-html"}, + {"shw", "application/presentations"}, + {"sit", "application/x-stuffit"}, + {"sjf", "application/octet-stream"}, + {"smi", "application/smil"}, + {"smil", "application/smil"}, + {"sml", "application/smil"}, + {"smp", "application/studiom"}, + {"snd", "audio/basic"}, + {"spc", "text/x-speech"}, + {"spl", "application/futuresplash"}, + {"spr", "application/x-sprite"}, + {"sprite", "application/x-sprite"}, + {"sql", "text/plain"}, + {"src", "application/x-wais-source"}, + {"ssi", "text/x-server-parsed-html"}, + {"stk", "application/hstu"}, + {"stream", "audio/x-qt-stream"}, + {"sv4cpio", "application/x-sv4cpio"}, + {"sv4crc", "application/x-sv4crc"}, + {"svf", "image/vnd"}, + {"svh", "image/svh"}, + {"svr", "x-world/x-svr"}, + {"swa", "application/x-director"}, + {"swf", "application/x-shockwave-flash"}, + {"t", "application/x-troff"}, + {"talk", "application/talker"}, + {"tar", "application/x-tar"}, + {"tbk", "application/toolbook"}, + {"tcl", "application/x-tcl"}, + {"tex", "application/x-tex"}, + {"texi", "application/x-texinfo"}, + {"texinfo", "application/x-texinfo"}, + {"text", "text/plain"}, + {"tgz", "application/gzip"}, + {"tgz", "application/x-gzip"}, + {"tif", "image/tiff"}, + {"tiff", "image/tiff"}, + {"tlk", "application/x-tlk"}, + {"tmv", "application/x-Parable-Thing"}, + {"torrent", "application/x-bittorrent"}, + {"tr", "application/x-troff"}, + {"troff", "application/x-troff"}, + {"tsi", "audio/tsplayer"}, + {"tsp", "application/dsptype"}, + {"tsq", "application/timestamp-query"}, + {"tsr", "application/timestamp-reply"}, + {"tsv", "text/tab-separated-values"}, + {"txt", "text/plain"}, + {"u98", "urdu/urdu98"}, + {"ucert", "application/x-x509-user-cert"}, + {"uin", "application/x-icq"}, + {"usercert", "application/x-x509-user-cert"}, + {"usr", "application/x-x509-user-cert"}, + {"ustar", "application/x-ustar"}, + {"vbd", "application/activexdocument"}, + {"vcd", "application/x-cdlink"}, + {"vcf", "text/x-vcard"}, + {"vew", "application/groupwise"}, + {"vgm", "video/x-videogram"}, + {"vgp", "video/x-videogram-plugin"}, + {"vgx", "video/x-videogram"}, + {"viv", "video/vnd.vivo"}, + {"vivo", "video/vnd.vivo"}, + {"vmd", "application/vocaltec-media-desc"}, + {"vmf", "application/vocaltec-media-file"}, + {"vmi", "application/x-dreamcast-vms-info"}, + {"vms", "application/x-dreamcast-vms"}, + {"vox", "audio/voxware"}, + {"vpa", "application/vpa"}, + {"vqe", "audio/x-twinvq-plugin"}, + {"vqf", "audio/x-twinvq"}, + {"vql", "audio/x-twinvq"}, + {"vrt", "x-world/x-vrt"}, + {"vts", "workbook/formulaone"}, + {"vtts", "workbook/formulaone"}, + {"w60", "application/wordperfect6.0"}, + {"w61", "application/wordperfect6.1"}, + {"waf", "plugin/wanimate"}, + {"wan", "plugin/wanimate"}, + {"wav", "audio/wav"}, + {"wav", "audio/x-wav"}, + {"wax", "audio/x-ms-wax"}, + {"wbmp", "image/vnd.wap.wbmp"}, + {"wi", "image/wavelet"}, + {"wid", "application/x-DemoShield"}, + {"wis", "application/x-InstallShield"}, + {"wlt", "application/x-mswallet"}, + {"wm", "video/x-ms-wm"}, + {"wma", "audio/x-ms-wma"}, + {"wmd", "application/x-ms-wmd"}, + {"wmf", "image/x-wmf"}, + {"wml", "x-world/x-vrml"}, + {"wml", "text/vnd.wap.wml"}, + {"wmlc", "application/vnd.wap.wmlc"}, + {"wmls", "text/vnd.wap.wmlscript"}, + {"wmlsc", "application/vnd.wap.wmlscriptc"}, + {"wmv", "video/x-ms-wmv"}, + {"wmx", "video/x-ms-wmx"}, + {"wmz", "application/x-ms-wmz"}, + {"wp", "application/wordperfect"}, + {"wp5", "application/wordperfect"}, + {"wpd", "application/wordperfect5.1"}, + {"wpd", "application/wordperfect"}, + {"wri", "application/write"}, + {"wrl", "x-world/x-vrml"}, + {"wrz", "x-world/x-vrml"}, + {"wtx", "audio/wtx"}, + {"wvx", "video/x-ms-wvx"}, + {"xbm", "image/x-xbitmap"}, + {"xdr", "video/x-videogram"}, + {"xhtml", "application/xhtml+xml"}, + {"xif", "image/vnd.xiff"}, + {"xla", "application/vnd.ms-excel"}, + {"xlc", "application/vnd.ms-excel"}, + {"xlm", "application/vnd.ms-excel"}, + {"xls", "application/vnd.ms-excel"}, + {"xls", "application/xls"}, + {"xlt", "application/vnd.ms-excel"}, + {"xlt", "application/xlt"}, + {"xlw", "application/vnd.ms-excel"}, + {"xml", "application/xml"}, + {"xml", "text/xml"}, + {"xpm", "image/x-xpixmap"}, + {"xwd", "image/x-xwindowdump"}, + {"z", "application/x-compress"}, + {"zip", "application/x-zip-compressed"}, + {"zip", "application/zip"}, + {"zip", "application/x-compressed"}, + {"zip", "multipart/x-zip"}, + {"zpa", "application/pcphoto"}}; + + protected static void initializeMaps() { + if (mimeType2Extension == null || extension2MimeType == null) { + mimeType2Extension = new HashMap(); + extension2MimeType = new HashMap(); + for (int i=0; i + + + + + + + + + + + + + + + + + + - - - - - - - + Index: src/modules/cforms/sitemap.xmap =================================================================== --- src/modules/cforms/sitemap.xmap (Revision 387571) +++ src/modules/cforms/sitemap.xmap (Arbeitskopie) @@ -37,16 +37,28 @@ + + + + + + + + + + + + + + + + + + - - - - - - - + Index: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVDocumentMatcher.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVDocumentMatcher.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVDocumentMatcher.java (Revision 0) @@ -0,0 +1,69 @@ +package org.apache.lenya.cms.cocoon.matching; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.Serviceable; +import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.matching.Matcher; +import org.apache.cocoon.sitemap.PatternException; +import org.apache.lenya.cms.publication.DocumentIdentityMap; +import org.apache.lenya.cms.publication.Publication; +import org.apache.lenya.cms.publication.PublicationException; +import org.apache.lenya.cms.publication.PublicationUtil; +import org.apache.lenya.cms.repository.RepositoryUtil; +import org.apache.lenya.cms.repository.Session; +import org.apache.lenya.cms.webdav.LenyaWebDAVUrl; +import org.apache.lenya.cms.webdav.LenyaWebDAVUrlException; + +public class LenyaWebDAVDocumentMatcher extends AbstractLogEnabled +implements Matcher, ThreadSafe, Serviceable +{ + protected ServiceManager manager; + + /* (non-Javadoc) + * @see org.apache.cocoon.matching.Matcher#match(java.lang.String, java.util.Map, org.apache.avalon.framework.parameters.Parameters) + */ + public Map match(String pattern, Map objectModel, Parameters parameters) + throws PatternException + { + Request request = ObjectModelHelper.getRequest(objectModel); + Session session = RepositoryUtil.getSession(request, getLogger()); + DocumentIdentityMap documentIdentityMap = + new DocumentIdentityMap(session, manager, getLogger()); + + Publication publication; + try { + publication = PublicationUtil.getPublication(manager, objectModel); + } catch (PublicationException pe) { + throw new PatternException("Error getting publication", pe); + } + try { + LenyaWebDAVUrl url = new LenyaWebDAVUrl(pattern, publication, + documentIdentityMap, this.manager, getLogger()); + if (url.isDocument()) { + if (getLogger().isDebugEnabled()) + getLogger().debug("Matched request with pattern [" + pattern + "]"); + return new HashMap(); + } else { + if (getLogger().isDebugEnabled()) + getLogger().debug("Did not match request with pattern [" + pattern + "]"); + return null; + } + } catch (LenyaWebDAVUrlException lwue) { + if (getLogger().isDebugEnabled()) + getLogger().debug("Did not match request with pattern [" + pattern + "]", lwue); + return null; + } + } + + public void service(ServiceManager manager) throws ServiceException { + this.manager = manager; + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVDocumentMatcher.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVResourceMatcher.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVResourceMatcher.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVResourceMatcher.java (Revision 0) @@ -0,0 +1,65 @@ +package org.apache.lenya.cms.cocoon.matching; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.Serviceable; +import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.matching.Matcher; +import org.apache.cocoon.sitemap.PatternException; +import org.apache.lenya.cms.publication.DocumentIdentityMap; +import org.apache.lenya.cms.publication.Publication; +import org.apache.lenya.cms.publication.PublicationException; +import org.apache.lenya.cms.publication.PublicationUtil; +import org.apache.lenya.cms.repository.RepositoryUtil; +import org.apache.lenya.cms.repository.Session; +import org.apache.lenya.cms.webdav.LenyaWebDAVUrl; +import org.apache.lenya.cms.webdav.LenyaWebDAVUrlException; + +public class LenyaWebDAVResourceMatcher extends AbstractLogEnabled +implements Matcher, Serviceable, ThreadSafe +{ + protected ServiceManager manager; + + public Map match(String pattern, Map objectModel, Parameters parameters) + throws PatternException { + Request request = ObjectModelHelper.getRequest(objectModel); + Session session = RepositoryUtil.getSession(request, getLogger()); + DocumentIdentityMap documentIdentityMap = + new DocumentIdentityMap(session, manager, getLogger()); + + Publication publication; + try { + publication = PublicationUtil.getPublication(manager, objectModel); + } catch (PublicationException pe) { + throw new PatternException("Error getting publication", pe); + } + try { + LenyaWebDAVUrl url = new LenyaWebDAVUrl(pattern, publication, + documentIdentityMap, this.manager, getLogger()); + if (url.isResource()) { + if (getLogger().isDebugEnabled()) + getLogger().debug("Matched request with pattern [" + pattern + "]"); + return new HashMap(); + } else { + if (getLogger().isDebugEnabled()) + getLogger().debug("Did not match request with pattern [" + pattern + "]"); + return null; + } + } catch (LenyaWebDAVUrlException lwue) { + if (getLogger().isDebugEnabled()) + getLogger().debug("Did not match request with pattern [" + pattern + "]", lwue); + return null; + } + } + + public void service(ServiceManager manager) throws ServiceException { + this.manager = manager; + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/matching/LenyaWebDAVResourceMatcher.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/WebDAVPropfindGenerator.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/WebDAVPropfindGenerator.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/WebDAVPropfindGenerator.java (Revision 0) @@ -0,0 +1,571 @@ +package org.apache.lenya.cms.cocoon.generation; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.service.ServiceSelector; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.SourceResolver; +import org.apache.excalibur.source.Source; +import org.apache.excalibur.source.SourceNotFoundException; +import org.apache.lenya.cms.metadata.dublincore.DublinCore; +import org.apache.lenya.cms.publication.Document; +import org.apache.lenya.cms.publication.DocumentBuildException; +import org.apache.lenya.cms.publication.DocumentBuilder; +import org.apache.lenya.cms.publication.DocumentException; +import org.apache.lenya.cms.publication.DocumentIdentifier; +import org.apache.lenya.cms.publication.Publication; +import org.apache.lenya.cms.publication.Resource; +import org.apache.lenya.cms.publication.ResourceType; +import org.apache.lenya.cms.publication.ResourcesManager; +import org.apache.lenya.cms.repository.Node; +import org.apache.lenya.cms.repository.RepositoryException; +import org.apache.lenya.cms.site.SiteManager; +import org.apache.lenya.cms.site.tree.SiteTree; +import org.apache.lenya.cms.site.tree.SiteTreeNode; +import org.apache.lenya.cms.webdav.LenyaWebDAVUrl; +import org.apache.lenya.cms.webdav.LenyaWebDAVUrlException; +import org.apache.lenya.cms.webdav.WebDAVXmlHelper; +import org.xml.sax.SAXException; + +public class WebDAVPropfindGenerator extends AbstractWebDAVGenerator { + protected final static boolean IS_COLLECTION_TRUE = true; + protected final static boolean IS_COLLECTION_FALSE = false; + + protected SiteManager siteManager; + protected SiteTree siteTree; + protected DocumentBuilder docBuilder; + protected ServiceSelector siteManagerSelector; + protected ServiceSelector docBuilderSelector; + protected ResourcesManager resourcesManager; + + + public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { + super.setup(resolver, objectModel, src, par); + + if (!webdavRequest.getMethod().equals(WEBDAV_METHOD_PROPFIND)) + throw new ProcessingException("Error processing PROPFIND request: Wrong method [" + webdavRequest.getMethod() + "]"); + + try { + siteManagerSelector = (ServiceSelector) this.manager.lookup(SiteManager.ROLE + + "Selector"); + siteManager = (SiteManager) siteManagerSelector.select(this.publication.getSiteManagerHint()); + + docBuilderSelector = (ServiceSelector) this.manager.lookup(DocumentBuilder.ROLE + + "Selector"); + docBuilder = (DocumentBuilder) docBuilderSelector.select(this.publication.getDocumentBuilderHint()); + + resourcesManager = (ResourcesManager) this.manager.lookup(ResourcesManager.ROLE); + + siteTree = (SiteTree)siteManager.getSiteStructure(documentIdentityMap, publication, Publication.AUTHORING_AREA); + } catch (Exception e) { + throw new ProcessingException(e); + } + + this.attributes.clear(); + } + + public void recycle() { + siteTree = null; + if (siteManagerSelector != null) { + if (siteManager != null) { + siteManagerSelector.release(siteManager); + siteManager = null; + } + this.manager.release(siteManagerSelector); + siteManagerSelector = null; + } + if (docBuilderSelector != null) { + if (docBuilder != null) { + docBuilderSelector.release(docBuilder); + docBuilder = null; + } + this.manager.release(docBuilderSelector); + docBuilderSelector = null; + } + if (resourcesManager != null) { + this.manager.release(resourcesManager); + resourcesManager = null; + } + super.recycle(); + } + + public void generate() + throws IOException, SAXException, ProcessingException + { + LenyaWebDAVUrl url; + + if ("/".equals(source)) { + url = null; + } else { + try { + url = new LenyaWebDAVUrl(this.source, + publication, documentIdentityMap, this.manager, getLogger()); + } catch (LenyaWebDAVUrlException lwue) { + throw new ProcessingException("Error parsing Lenya WebDAV url [" + + this.source + "]", lwue); + } + } + + this.contentHandler.startDocument(); + this.contentHandler.startPrefixMapping(WEBDAV_PREFIX, WEBDAV_NS); + + this.contentHandler.startElement(WEBDAV_NS, MULTISTATUS, + WEBDAV_PREFIX + ":" + MULTISTATUS, this.attributes); + + if (url == null) { + writeResponse(null, IS_COLLECTION_TRUE, webdavRequest.getDepth()); + } else if (url.isCollection() || url.isDocument()) { + writeResponse(url.getDocument(), url.isCollection(), webdavRequest.getDepth()); + } else if (url.isResource()) { + writeResponse(url.getResource()); + } + + this.contentHandler.endElement(WEBDAV_NS, MULTISTATUS, + WEBDAV_PREFIX + ":" + MULTISTATUS); + + this.contentHandler.endPrefixMapping(WEBDAV_PREFIX); + this.contentHandler.endDocument(); + + this.httpResponse.setStatus(WEBDAV_MULTI_STATUS); + } + + /** + * Write XML response tag for a given document. + * @param doc Document to write XML response tag for. + * @param asCollection true if document should be handled as a collection, otherwise false + * @param depth Depth of request. Either WEBDAV_DEPTH_0, WEBDAV_DETPH_1, or WEBDAV_DEPTH_INFINITY + * @throws ProcessingException + * @throws SAXException + */ + protected void writeResponse(Document doc, boolean asCollection, String depth) + throws ProcessingException, SAXException + { + // TODO: + try { + if (doc != null) { + Source resSrc = resolver.resolveURI("cocoon://lenya/modules/xhtml/webdav:get:" + doc.getId()); + getLogger().debug("FELIX exists: " + resSrc.exists()); + } + } catch (MalformedURLException e) { + // TODO: DEBUG + getLogger().debug("Error resolving URI", e); + // throw new LenyaWebDAVUrlException("Error resolving URI", e); + } catch (IOException e) { + // TODO: DEBUG + getLogger().debug("Error resolving URI", e); + // throw new LenyaWebDAVUrlException("Error resolving URI", e); + } + + this.contentHandler.startElement(WEBDAV_NS, RESPONSE, WEBDAV_PREFIX + ":" + RESPONSE, this.attributes); + if (doc == null) { + WebDAVXmlHelper.writeHRef("/" + publication.getId() + "/" + LENYA_WEBDAV_CONTEXT + "/", + this.contentHandler, this.attributes); + } else { + if (asCollection) { + WebDAVXmlHelper.writeHRef("/" + publication.getId() + "/" + LENYA_WEBDAV_CONTEXT + + doc.getId() + "/", this.contentHandler, this.attributes); + } else { + WebDAVXmlHelper.writeHRef("/" + publication.getId() + "/" + LENYA_WEBDAV_CONTEXT + + doc.getId() + "/" + doc.getName() + "_" + doc.getLanguage() + + "." + doc.getExtension(), this.contentHandler, this.attributes); + } + } + this.contentHandler.startElement(WEBDAV_NS, PROPSTAT, WEBDAV_PREFIX + ":" + PROPSTAT, this.attributes); + Map requestedProperties = webdavRequest.getRequestedProperties(); + Map unsupportedProperties = new HashMap(); + writeProperties(doc, asCollection, requestedProperties, unsupportedProperties); + WebDAVXmlHelper.writeStatus(WEBDAV_STATUS_MSG_OK, this.contentHandler, this.attributes); + this.contentHandler.endElement(WEBDAV_NS, PROPSTAT, WEBDAV_PREFIX + ":" + PROPSTAT); + // Write unsupported properties with a 404 status code. + unsupportedProperties.remove(WEBDAV_NS + ":" + ALLPROP); + if (unsupportedProperties.size() > 0) + writeUnsupportedProperties(unsupportedProperties); + this.contentHandler.endElement(WEBDAV_NS, RESPONSE, WEBDAV_PREFIX + ":" + RESPONSE); + if (depth == WEBDAV_DEPTH_0) { + // Nothing to do. + } else if (depth == WEBDAV_DEPTH_1 || depth == WEBDAV_DEPTH_INFINITY) { + // Write language documents. + if (doc != null) { + String[] languages; + try { + languages = doc.getLanguages(); + } catch (DocumentException de) { + throw new ProcessingException("Error getting languages for document [" + doc.getId() + "]", de); + } + for (int i=0; i 0) + writeUnsupportedProperties(unsupportedProperties); + this.contentHandler.endElement(WEBDAV_NS, RESPONSE, WEBDAV_PREFIX + ":" + RESPONSE); + } + + /** + * Write all supported properties of resource. + * @param resource Resource object for which the requested properties should be written. + * @param requestedProperties + * @param unsupportedProperties + * @throws ProcessingException + * @throws SAXException + */ + protected void writeProperties(Resource resource, Map requestedProperties, Map unsupportedProperties) + throws ProcessingException, SAXException + { + Map unsupProps = new HashMap(requestedProperties); + this.contentHandler.startElement(WEBDAV_NS, PROP, WEBDAV_PREFIX + ":" + PROP, this.attributes); + try { + if (requestedProperties.containsKey(WEBDAV_NS + ":" + DISPLAYNAME) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeDisplayName(resource.getName(), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + DISPLAYNAME); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETLASTMODIFIED) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeGetLastModified(new Date(resource.getLastModified()), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + GETLASTMODIFIED); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + CREATIONDATE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + // FIXME: Get correct date. Not possible yet with given API. + WebDAVXmlHelper.writeCreationDate(new Date(0), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + CREATIONDATE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + RESOURCETYPE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeResourceType(IS_COLLECTION_FALSE, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + RESOURCETYPE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETCONTENTTYPE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeGetContentType(resource.getMimeType(), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + GETCONTENTTYPE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETCONTENTLENGTH) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + String contentLength = Long.toString(resource.getContentLength()); + WebDAVXmlHelper.writeGetContentLength(contentLength, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + GETCONTENTLENGTH); + } + // TODO: Lenya Issue: Implement locking for resources. + if (requestedProperties.containsKey(WEBDAV_NS + ":" + SUPPORTEDLOCK) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeSupportedLock(false, false, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + SUPPORTEDLOCK); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + LOCKDISCOVERY) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + // TODO: Lock discovery + WebDAVXmlHelper.writeLockDiscovery(this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + LOCKDISCOVERY); + } + } catch (SourceNotFoundException snfe) { + throw new ProcessingException(snfe); + } + this.contentHandler.endElement(WEBDAV_NS, PROP, WEBDAV_PREFIX + ":" + PROP); + // Add all unsupported properties to passed parameter. + unsupportedProperties.putAll(unsupProps); + } + + /** + * Write the properties for a document. + * @param doc + * @param asCollection + * @param requestedProperties + * @param unsupportedProperties + * @throws ProcessingException + * @throws SAXException + */ + protected void writeProperties(Document doc, boolean asCollection, Map requestedProperties, + Map unsupportedProperties) + throws ProcessingException, SAXException + { + Map unsupProps = new HashMap(requestedProperties); + this.contentHandler.startElement(WEBDAV_NS, PROP, WEBDAV_PREFIX + ":" + PROP, this.attributes); + // WebDAV root context. + if (doc == null) { + if (requestedProperties.containsKey(WEBDAV_NS + ":" + DISPLAYNAME) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeDisplayName(LENYA_WEBDAV_CONTEXT, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + DISPLAYNAME); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETLASTMODIFIED) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + // Write dummy last modification date for WebDAV root. + WebDAVXmlHelper.writeGetLastModified(new Date(0), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + GETLASTMODIFIED); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + CREATIONDATE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + // Write dummy creation date for WebDAV root. + WebDAVXmlHelper.writeCreationDate(new Date(0), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + CREATIONDATE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + RESOURCETYPE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeResourceType(IS_COLLECTION_TRUE, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + RESOURCETYPE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + SUPPORTEDLOCK) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeSupportedLock(false, false, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + SUPPORTEDLOCK); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + LOCKDISCOVERY) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeLockDiscovery(this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + LOCKDISCOVERY); + } + } else { // Document context. + if (requestedProperties.containsKey(WEBDAV_NS + ":" + DISPLAYNAME) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeDisplayName(doc.getId(), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + DISPLAYNAME); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETLASTMODIFIED) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeGetLastModified(doc.getLastModified(), + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + GETLASTMODIFIED); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + CREATIONDATE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + Date creationDate; + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String creationDateString = + doc.getMetaDataManager().getDublinCoreMetaData().getFirstValue(DublinCore.ELEMENT_DATE); + if (creationDateString != null) { + try { + creationDate = sdf.parse(creationDateString); + } catch (ParseException e) { + getLogger().error("Error parsing creation date [" + + creationDateString + "] for [" + doc.getId() + "]"); + creationDate = new Date(0); + } + } else { + getLogger().error("Error getting creation date [" + doc.getId() + "]"); + creationDate = new Date(0); + } + } catch (DocumentException de) { + throw new ProcessingException("Error getting creation date", de); + } + WebDAVXmlHelper.writeCreationDate(creationDate, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + CREATIONDATE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + RESOURCETYPE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + WebDAVXmlHelper.writeResourceType(asCollection, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + RESOURCETYPE); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETCONTENTTYPE) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + if (!asCollection) { + try { + String contentType = doc.getRepositoryNode().getMimeType(); + WebDAVXmlHelper.writeGetContentType(contentType, + this.contentHandler, this.attributes); + } catch (RepositoryException re) { + throw new ProcessingException("Error getting mime-type", re); + } + unsupProps.remove(WEBDAV_NS + ":" + GETCONTENTTYPE); + } + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + GETCONTENTLENGTH) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + // FIXME: Hack for "opendocument" resource type. + ResourceType rt; + try { + rt = doc.getResourceType(); + } catch (DocumentException de) { + throw new ProcessingException("Error getting resource type [" + doc.getId() + "]", de); + } + if (!rt.getName().equals("opendocument")) { + if (!asCollection) { + try { + String contentLength = Long.toString(doc.getRepositoryNode().getContentLength()); + WebDAVXmlHelper.writeGetContentLength(contentLength, + this.contentHandler, this.attributes); + } catch (RepositoryException re) { + throw new ProcessingException("Error getting content-length", re); + } + unsupProps.remove(WEBDAV_NS + ":" + GETCONTENTLENGTH); + } + unsupProps.remove(WEBDAV_NS + ":" + GETCONTENTLENGTH); + } + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + SUPPORTEDLOCK) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + if (asCollection) + WebDAVXmlHelper.writeSupportedLock(true, false, + this.contentHandler, this.attributes); + else + WebDAVXmlHelper.writeSupportedLock(false, false, + this.contentHandler, this.attributes); + unsupProps.remove(WEBDAV_NS + ":" + SUPPORTEDLOCK); + } + if (requestedProperties.containsKey(WEBDAV_NS + ":" + LOCKDISCOVERY) || + requestedProperties.containsKey(WEBDAV_NS + ":" + ALLPROP)) + { + Node repoNode = doc.getRepositoryNode(); + boolean isCheckedOut; + try { + isCheckedOut = repoNode.isCheckedOut(); + } catch (RepositoryException e) { + throw new ProcessingException("Error getting check-out state of document [" + doc.getId() + "]"); + } + String lockOwner; + try { + lockOwner = repoNode.checkedOutBy(); + } catch (RepositoryException e) { + throw new ProcessingException("Error getting check-out user identity [" + doc.getId() + "]"); + } + if (isCheckedOut) { + // FIXME: Create WebDAV standard conformant lock token. + WebDAVXmlHelper.writeLockDiscovery(EXCLUSIVE, WRITE, WEBDAV_DEPTH_0, lockOwner, + WEBDAV_TIMEOUT_INFINITE, "", + this.contentHandler, this.attributes); + } else { + WebDAVXmlHelper.writeLockDiscovery(this.contentHandler, this.attributes); + } + unsupProps.remove(WEBDAV_NS + ":" + LOCKDISCOVERY); + } + } + this.contentHandler.endElement(WEBDAV_NS, PROP, WEBDAV_PREFIX + ":" + PROP); + // Add all unsupported properties to passed parameter. + unsupportedProperties.putAll(unsupProps); + } + + /** + * Write unsupported elements. + * @param unsupportedProperties Map with unsupported properties. The keys are the qualified property names. + * @throws SAXException + */ + protected void writeUnsupportedProperties(Map unsupportedProperties) throws SAXException { + this.contentHandler.startElement(WEBDAV_NS, PROPSTAT, WEBDAV_PREFIX + ":" + PROPSTAT, this.attributes); + this.contentHandler.startElement(WEBDAV_NS, PROP, WEBDAV_PREFIX + ":" + PROP, this.attributes); + Iterator iter = unsupportedProperties.keySet().iterator(); + while (iter.hasNext()) { + String property = (String)iter.next(); + int sepIndex = property.lastIndexOf(":"); + String ns = property.substring(0, sepIndex); + String localName = property.substring(sepIndex+1); + this.contentHandler.startPrefixMapping("", ns); + this.contentHandler.startElement(ns, localName, localName, this.attributes); + this.contentHandler.endElement(ns, localName, localName); + this.contentHandler.endPrefixMapping(""); + } + this.contentHandler.endElement(WEBDAV_NS, PROP, WEBDAV_PREFIX + ":" + PROP); + WebDAVXmlHelper.writeStatus(WEBDAV_STATUS_MSG_NOT_FOUND, + this.contentHandler, this.attributes); + this.contentHandler.endElement(WEBDAV_NS, PROPSTAT, WEBDAV_PREFIX + ":" + PROPSTAT); + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/WebDAVPropfindGenerator.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/AbstractWebDAVGenerator.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/AbstractWebDAVGenerator.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/AbstractWebDAVGenerator.java (Revision 0) @@ -0,0 +1,79 @@ +package org.apache.lenya.cms.cocoon.generation; + +import java.io.IOException; +import java.util.Map; + +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.SourceResolver; +import org.apache.cocoon.environment.http.HttpRequest; +import org.apache.cocoon.environment.http.HttpResponse; +import org.apache.cocoon.generation.ServiceableGenerator; +import org.apache.lenya.cms.publication.DocumentIdentityMap; +import org.apache.lenya.cms.publication.Publication; +import org.apache.lenya.cms.publication.PublicationException; +import org.apache.lenya.cms.publication.PublicationUtil; +import org.apache.lenya.cms.repository.RepositoryUtil; +import org.apache.lenya.cms.repository.Session; +import org.apache.lenya.cms.webdav.WebDAVConstants; +import org.apache.lenya.cms.webdav.WebDAVRequest; +import org.apache.lenya.cms.webdav.WebDAVRequestException; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +public abstract class AbstractWebDAVGenerator +extends ServiceableGenerator +implements WebDAVConstants +{ + protected Publication publication; + protected Session repoSession; + protected DocumentIdentityMap documentIdentityMap; + protected HttpRequest httpRequest; + protected HttpResponse httpResponse; + protected WebDAVRequest webdavRequest; + + protected AttributesImpl attributes = null; + + public AbstractWebDAVGenerator() { + this.attributes = new AttributesImpl(); + } + + public void setup(SourceResolver resolver, Map objectModel, + String src, Parameters par) throws ProcessingException, + SAXException, IOException + { + super.setup(resolver, objectModel, src, par); + this.attributes.clear(); + this.httpRequest = (HttpRequest)ObjectModelHelper.getRequest(objectModel); + this.httpResponse = (HttpResponse)ObjectModelHelper.getResponse(objectModel); + if (this.source == null) + throw new ProcessingException("Error setting up generator: 'src' attribute missing"); + try { + this.publication = PublicationUtil.getPublication(manager, objectModel); + } catch (PublicationException pe) { + throw new ProcessingException("Error getting publication", pe); + } + this.repoSession = RepositoryUtil.getSession(httpRequest, getLogger()); + this.documentIdentityMap = new DocumentIdentityMap(repoSession, manager, getLogger()); + this.webdavRequest = new WebDAVRequest(manager, getLogger()); + try { + this.webdavRequest.parseRequest(httpRequest); + } catch (WebDAVRequestException wre) { + throw new ProcessingException("Error parsing WebDAV request", wre); + } + } + + public void recycle() { + // Invalidating session as WebDAV is state-less. + org.apache.cocoon.environment.Session session = this.httpRequest.getSession(); + if (session != null) { + try { + session.invalidate(); + } catch (IllegalStateException ise) { + getLogger().error("Error invalidating session", ise); + } + } + super.recycle(); + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/cocoon/generation/AbstractWebDAVGenerator.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequestException.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequestException.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequestException.java (Revision 0) @@ -0,0 +1,21 @@ +package org.apache.lenya.cms.webdav; + +public class WebDAVRequestException extends Exception { + static final long serialVersionUID = 1L; + + public WebDAVRequestException() { + super(); + } + + public WebDAVRequestException(String message) { + super(message); + } + + public WebDAVRequestException(String message, Throwable cause) { + super(message, cause); + } + + public WebDAVRequestException(Throwable cause) { + super(cause); + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequestException.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequest.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequest.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequest.java (Revision 0) @@ -0,0 +1,177 @@ +package org.apache.lenya.cms.webdav; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.http.HttpRequest; +import org.apache.cocoon.xml.XMLUtils; +import org.apache.excalibur.xml.dom.DOMParser; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class WebDAVRequest implements WebDAVConstants { + protected ServiceManager serviceManager; + protected Logger log; + + protected String depth; + protected String method; + protected HashMap reqProperties; + + public WebDAVRequest(ServiceManager serviceManager, Logger log) { + this.serviceManager = serviceManager; + this.log = log; + this.reqProperties = new HashMap(); + } + + public void parseRequest(HttpRequest request) throws WebDAVRequestException { + if (log.isDebugEnabled()) + log.debug("Parsing WebDAV request ..."); + parseDepthHeader(request); + if (log.isDebugEnabled()) + log.debug("WebDAV request: [Depth=" + depth + "]"); + parseMethod(request); + if (log.isDebugEnabled()) + log.debug("WebDAV request: [Method=" + method + "]"); + + DOMParser parser; + try { + parser = (DOMParser)serviceManager.lookup(DOMParser.ROLE); + } catch (ServiceException se) { + throw new WebDAVRequestException("Error looking up parser component", se); + } + // TODO: Check for empty request body. + Document doc; + try { + doc = parser.parseDocument(new InputSource(request.getInputStream())); + } catch (SAXException e) { + throw new WebDAVRequestException("Error parsing WebDAV request", e); + } catch (IOException e) { + throw new WebDAVRequestException(e); + } + // Log WebDAV request. + if (log.isDebugEnabled()) { + try { + log.debug("Serializing WebDAV request: \n" + XMLUtils.serializeNode(doc)); + } catch (ProcessingException pe) { + log.error("Error serializing WebDAV request", pe); + } + } + Node node = doc.getFirstChild(); + if (node.getNamespaceURI().equals(WEBDAV_NS) && node.getLocalName().equals(PROPFIND)) { + parsePropfindRequest(node); + } else { + throw new WebDAVRequestException("Error parsing WebDAV request: unknown node [" + + node.getNamespaceURI() + ":" + node.getLocalName()); + } + } + + protected void parseDepthHeader(HttpRequest request) { + String headerDepth = request.getHeader(HEADER_DEPTH); + + if (headerDepth == null || headerDepth.equals(WEBDAV_DEPTH_INFINITY)) { + depth = WEBDAV_DEPTH_INFINITY; + } else if (headerDepth.equals(WEBDAV_DEPTH_0)) { + depth = WEBDAV_DEPTH_0; + } else if (headerDepth.equals(WEBDAV_DEPTH_1)) { + depth = WEBDAV_DEPTH_1; + } else { + depth = WEBDAV_DEPTH_INFINITY; + log.error("Error parsing WebDAV 'Depth' header [" + + headerDepth + "]. Using default 'depth' header value!"); + } + } + + protected void parsePropfindRequest(Node node) throws WebDAVRequestException { + Node propNode = node.getFirstChild(); + while (propNode != null && propNode.getNodeType() != Node.ELEMENT_NODE) { + propNode = propNode.getNextSibling(); + } + if (propNode != null && + propNode.getNamespaceURI().equals(WEBDAV_NS) && + propNode.getLocalName().equals(ALLPROP)) + { + reqProperties.put(WEBDAV_NS + ":" + ALLPROP, null); + } else if (propNode != null && + propNode.getNamespaceURI().equals(WEBDAV_NS) && + propNode.getLocalName().equals(PROPNAME)) + { + reqProperties.put(WEBDAV_NS + ":" + PROPNAME, null); + } else if (propNode != null && + propNode.getNamespaceURI().equals(WEBDAV_NS) && + propNode.getLocalName().equals(PROP)) + { + NodeList reqPropertyList = propNode.getChildNodes(); + for (int i=0; i, <" + WEBDAV_NS + ":" + ALLPROP + "/> or <" + + WEBDAV_NS + ":" + PROPNAME + "/> node"); + } + + } + + protected void parseMethod(HttpRequest request) { + String headerMethod = request.getMethod().toUpperCase(); + if (headerMethod.equals(WEBDAV_METHOD_GET)) { + this.method = WEBDAV_METHOD_GET; + } else if (headerMethod.equals(WEBDAV_METHOD_HEAD)) { + this.method = WEBDAV_METHOD_HEAD; + } else if (headerMethod.equals(WEBDAV_METHOD_POST)) { + this.method = WEBDAV_METHOD_POST; + } else if (headerMethod.equals(WEBDAV_METHOD_OPTIONS)) { + this.method = WEBDAV_METHOD_OPTIONS; + } else if (headerMethod.equals(WEBDAV_METHOD_PROPFIND)) { + this.method = WEBDAV_METHOD_PROPFIND; + } else if (headerMethod.equals(WEBDAV_METHOD_PROPPATCH)) { + this.method = WEBDAV_METHOD_PROPFIND; + } else if (headerMethod.equals(WEBDAV_METHOD_PUT)) { + this.method = WEBDAV_METHOD_PUT; + } else if (headerMethod.equals(WEBDAV_METHOD_MKCOL)) { + this.method = WEBDAV_METHOD_MKCOL; + } else if (headerMethod.equals(WEBDAV_METHOD_DELETE)) { + this.method = WEBDAV_METHOD_DELETE; + } else if (headerMethod.equals(WEBDAV_METHOD_MOVE)) { + this.method = WEBDAV_METHOD_MOVE; + } else if (headerMethod.equals(WEBDAV_METHOD_COPY)) { + this.method = WEBDAV_METHOD_COPY; + } else if (headerMethod.equals(WEBDAV_METHOD_LOCK)) { + this.method = WEBDAV_METHOD_LOCK; + } else if (headerMethod.equals(WEBDAV_METHOD_UNLOCK)) { + this.method = WEBDAV_METHOD_UNLOCK; + } + } + + public String getDepth() { + return depth; + } + + public String getMethod() { + return method; + } + + /** + * Returns a cloned map of the requested properties. + * @return Cloned map of requested properties or null if it's not a PROPFIND request. + */ + public Map getRequestedProperties() { + if (method != WEBDAV_METHOD_PROPFIND) + return null; + else + return (Map)reqProperties.clone(); + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVRequest.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrlException.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrlException.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrlException.java (Revision 0) @@ -0,0 +1,25 @@ +package org.apache.lenya.cms.webdav; + +public class LenyaWebDAVUrlException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public LenyaWebDAVUrlException() { + super(); + } + + public LenyaWebDAVUrlException(String message) { + super(message); + } + + public LenyaWebDAVUrlException(Throwable cause) { + super(cause); + } + + public LenyaWebDAVUrlException(String message, Throwable cause) { + super(message, cause); + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrlException.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrl.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrl.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrl.java (Revision 0) @@ -0,0 +1,189 @@ +package org.apache.lenya.cms.webdav; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.ServiceSelector; +import org.apache.lenya.cms.publication.Document; +import org.apache.lenya.cms.publication.DocumentBuildException; +import org.apache.lenya.cms.publication.DocumentBuilder; +import org.apache.lenya.cms.publication.DocumentException; +import org.apache.lenya.cms.publication.DocumentIdentifier; +import org.apache.lenya.cms.publication.DocumentIdentityMap; +import org.apache.lenya.cms.publication.Publication; +import org.apache.lenya.cms.publication.Resource; +import org.apache.lenya.cms.publication.ResourcesManager; + +public class LenyaWebDAVUrl { + /** + * Pattern for matching lenya document WebDAV URL. + */ + protected static Pattern lenyaDocPattern = + Pattern.compile("^/(.*)([^/]*)/\\2_([^/]{2})\\.[^/]*$"); + /** + * Pattern for matching lenya document resource (asset) WebDAV URL. + */ + protected static Pattern lenyaResourcePattern = + Pattern.compile("^/(.+)/([^/.]+\\.[^/.]+)$"); + /** + * Pattern for matching a WebDAV collection URL. + */ + protected static Pattern collectionPattern = + Pattern.compile("^/([^.]+)/?$"); + + protected String url; + protected Publication publication; + protected DocumentIdentityMap documentIdentityMap; + protected ServiceManager serviceManager; + protected Logger logger; + protected boolean isValid = false; + protected boolean isDocument = false; + protected boolean isResource = false; + protected boolean isCollection = false; + protected Document document = null; + protected Resource resource = null; + + public LenyaWebDAVUrl(String url, Publication publication, + DocumentIdentityMap documentIdentityMap, + ServiceManager serviceManager, Logger logger) + throws LenyaWebDAVUrlException + { + this.url = url; + this.publication = publication; + this.documentIdentityMap = documentIdentityMap; + this.serviceManager = serviceManager; + this.logger = logger; + parseUrl(); + } + + protected void parseUrl() throws LenyaWebDAVUrlException { + ServiceSelector docBuilderSelector = null; + DocumentBuilder docBuilder = null; + ResourcesManager resourcesManager = null; + try { + docBuilderSelector = (ServiceSelector)this.serviceManager.lookup(DocumentBuilder.ROLE + + "Selector"); + docBuilder = (DocumentBuilder)docBuilderSelector.select( + this.publication.getDocumentBuilderHint()); + resourcesManager = (ResourcesManager)this.serviceManager.lookup(ResourcesManager.ROLE); + + String docId; + String language; + Matcher collectionMatcher = collectionPattern.matcher(this.url); + Matcher docMatcher = lenyaDocPattern.matcher(this.url); + Matcher resourceMatcher = lenyaResourcePattern.matcher(this.url); + if (collectionMatcher.matches()) { // Is request URL a collection? + if (collectionMatcher.group(1).endsWith("/")) { + docId = "/" + collectionMatcher.group(1).substring(0, + collectionMatcher.group(1).length()-1); + } else { + docId = "/" + collectionMatcher.group(1); + } + language = publication.getDefaultLanguage(); + DocumentIdentifier docIdentifier = new DocumentIdentifier(publication, + Publication.AUTHORING_AREA, docId, language); + try { + document = docBuilder.buildDocument(documentIdentityMap, docIdentifier); + } catch (DocumentBuildException dbe) { + throw new LenyaWebDAVUrlException("Error building document", dbe); + } + boolean docExists = false; + try { + docExists = document.existsInAnyLanguage(); + } catch (DocumentException de) { + throw new LenyaWebDAVUrlException("Error checking language existance", de); + } + if (docExists) + isCollection = true; + else + document = null; + } else if (docMatcher.matches()) { // Is requested URL a document? + docId = "/" + docMatcher.group(1) + docMatcher.group(2); + language = docMatcher.group(3); + DocumentIdentifier docIdentifier = new DocumentIdentifier(publication, Publication.AUTHORING_AREA, docId, language); + try { + document = docBuilder.buildDocument(documentIdentityMap, docIdentifier); + } catch (DocumentBuildException dbe) { + throw new LenyaWebDAVUrlException("Error building document", dbe); + } + boolean docExists = false; + try { + docExists = document.existsInAnyLanguage(); + } catch (DocumentException de) { + throw new LenyaWebDAVUrlException("Error checking language existance", de); + } + if (docExists) + isDocument = true; + else + document = null; + } else if (resourceMatcher.matches()) { // Is requested URL a resource? + docId = "/" + resourceMatcher.group(1); + String resourceName = resourceMatcher.group(2); + language = publication.getDefaultLanguage(); + DocumentIdentifier docIdentifier = new DocumentIdentifier(publication, Publication.AUTHORING_AREA, docId, language); + try { + document = docBuilder.buildDocument(documentIdentityMap, docIdentifier); + } catch (DocumentBuildException dbe) { + throw new LenyaWebDAVUrlException("Error building document", dbe); + } + boolean docExists = false; + try { + docExists = document.existsInAnyLanguage(); + } catch (DocumentException de) { + throw new LenyaWebDAVUrlException("Error checking language existance", de); + } + + if (docExists) { + // TODO: DEBUG + logger.debug("FELIX: Document exists: " + document.getId()); + logger.debug("FELIX: Checking resource: " + resourceName); + resource = resourcesManager.getResource(document, resourceName); + isResource = true; + } else { + // TODO: DEBUG + logger.debug("FELIX: Document does not exists: " + document.getId()); + logger.debug("FELIX: Resource not found: " + resourceName); + document = null; + resource = null; + } + } else { + throw new LenyaWebDAVUrlException("Malformed Lenya WebDAV url [" + url + "]"); + } + } catch (ServiceException se) { + throw new LenyaWebDAVUrlException("Error looking up component", se); + } finally { + if (docBuilderSelector != null) { + if (docBuilder != null) { + docBuilderSelector.release(docBuilder); + } + serviceManager.release(docBuilderSelector); + } + if (resourcesManager != null) { + serviceManager.release(resourcesManager); + } + } + } + + public boolean isDocument() { + return isDocument; + } + + public boolean isResource() { + return isResource; + } + + public Document getDocument() { + return document; + } + + public Resource getResource() { + return resource; + } + + public boolean isCollection() { + return isCollection; + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/LenyaWebDAVUrl.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVConstants.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVConstants.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVConstants.java (Revision 0) @@ -0,0 +1,109 @@ +package org.apache.lenya.cms.webdav; + +public interface WebDAVConstants { + final static String WEBDAV_PREFIX = "D"; + final static String WEBDAV_NS = "DAV:"; + + final static String ACTIVELOCK = "activelock"; + final static String DEPTH = "depth"; + final static String LOCKTOKEN = "locktoken"; + final static String TIMEOUT = "timeout"; + final static String COLLECTION = "collection"; + final static String HREF = "href"; + final static String LINK = "link"; + final static String DST = "dst"; + final static String SRC = "src"; + final static String LOCKENTRY = "lockentry"; + final static String LOCKINFO = "lockinfo"; + final static String LOCKSCOPE = "lockscope"; + final static String EXCLUSIVE = "exclusive"; + final static String SHARED = "shared"; + final static String LOCKTYPE = "locktype"; + final static String WRITE = "write"; + final static String MULTISTATUS = "multistatus"; + final static String RESPONSE = "response"; + final static String PROPSTAT = "propstat"; + final static String STATUS = "status"; + final static String RESPONSEDESCRIPTION = "responsedescription"; + final static String OWNER = "owner"; + final static String PROP = "prop"; + final static String PROPERTYBEHAVIOUR = "propertybehaviour"; + final static String KEEPALIVE = "keepalive"; + final static String OMIT = "omit"; + final static String PROPERTYUPDATE = "propertyupdate"; + final static String REMOVE = "remove"; + final static String SET = "set"; + final static String PROPFIND = "propfind"; + final static String ALLPROP = "allprop"; + final static String PROPNAME = "propname"; + final static String CREATIONDATE = "creationdate"; + final static String DISPLAYNAME = "displayname"; + final static String GETCONTENTLANGUAGE = "getcontentlanguage"; + final static String GETCONTENTLENGTH = "getcontentlength"; + final static String GETCONTENTTYPE = "getcontenttype"; + final static String GETETAG = "getetag"; + final static String GETLASTMODIFIED = "getlastmodified"; + final static String LOCKDISCOVERY = "lockdiscovery"; + final static String RESOURCETYPE = "resourcetype"; + final static String SOURCE = "source"; + final static String SUPPORTEDLOCK = "supportedlock"; + + final static String HEADER_DEPTH = "Depth"; + final static String WEBDAV_DEPTH_0 = "0"; + final static String WEBDAV_DEPTH_1 = "1"; + final static String WEBDAV_DEPTH_INFINITY = "infinity"; + final static String WEBDAV_METHOD_GET = "GET"; + final static String WEBDAV_METHOD_HEAD = "HEAD"; + final static String WEBDAV_METHOD_POST = "POST"; + final static String WEBDAV_METHOD_OPTIONS = "OPTIONS"; + final static String WEBDAV_METHOD_PROPFIND = "PROPFIND"; + final static String WEBDAV_METHOD_PROPPATCH = "PROPPATCH"; + final static String WEBDAV_METHOD_PUT = "PUT"; + final static String WEBDAV_METHOD_MKCOL = "MKCOL"; + final static String WEBDAV_METHOD_DELETE = "DELETE"; + final static String WEBDAV_METHOD_MOVE = "MOVE"; + final static String WEBDAV_METHOD_COPY = "COPY"; + final static String WEBDAV_METHOD_LOCK = "LOCK"; + final static String WEBDAV_METHOD_UNLOCK = "UNLOCK"; + + // Numeric status codes. + /** + * WebDAV Status-Code 102: Processing. + */ + public final static int WEBDAV_PROCESSING = 102; + /** + * WebDAV Status-Code 207: Multi-Status. + */ + public final static int WEBDAV_MULTI_STATUS = 207; + + // Literal status codes. + /** + * WebDAV Status-Code 200: OK. + */ + final static String WEBDAV_STATUS_MSG_OK = "HTTP/1.1 200 OK"; + /** + * WebDAV Status-Code 422: Unprocessable Entity. + */ + final static String WEBDAV_STATUS_MSG_UNPROCESSABLE_ENTITY = "HTTP/1.1 422 Unprocessable Entity"; + /** + * WebDAV Status-Code 404: Not Found. + */ + final static String WEBDAV_STATUS_MSG_NOT_FOUND = "HTTP/1.1 404 Not Found"; + /** + * WebDAV Status-Code 423: Locked. + */ + final static String WEBDAV_STATUS_MSG_LOCKED = "HTTP/1.1 423 Locked"; + /** + * WebDAV Status-Code 424: Failed Dependency. + */ + final static String WEBDAV_STATUS_MSG_FAILED_DEPENDENCY = "HTTP/1.1 424 Failed Dependency"; + /** + * WebDAV Status-Code 507: Insufficient Storage. + */ + final static String WEBDAV_STATUS_MSG_INSUFFICIENT_STORAGE = "HTTP/1.1 507 Insufficient Storage"; + + final static String LENYA_WEBDAV_CONTEXT = "webdav2"; + + final static String WEBDAV_TIMEOUT_INFINITE = "Infinite"; + +} \ No newline at end of file Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVConstants.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVXmlHelper.java =================================================================== --- src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVXmlHelper.java (Revision 0) +++ src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVXmlHelper.java (Revision 0) @@ -0,0 +1,162 @@ +package org.apache.lenya.cms.webdav; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +public class WebDAVXmlHelper implements WebDAVConstants { + public static void writeStatus(String statusMsg, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, STATUS, WEBDAV_PREFIX + ":" + STATUS, attributes); + contentHandler.characters(statusMsg.toCharArray(), 0, statusMsg.length()); + contentHandler.endElement(WEBDAV_NS, STATUS, WEBDAV_PREFIX + ":" + STATUS); + } + + public static void writeHRef(String href, ContentHandler contentHandler, Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, HREF, WEBDAV_PREFIX + ":" + HREF, attributes); + contentHandler.characters(href.toCharArray(), 0, href.length()); + contentHandler.endElement(WEBDAV_NS, HREF, WEBDAV_PREFIX + ":" + HREF); + } + + public static void writeDisplayName(String displayName, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, DISPLAYNAME, WEBDAV_PREFIX + ":" + DISPLAYNAME, attributes); + contentHandler.characters(displayName.toCharArray(), 0, displayName.length()); + contentHandler.endElement(WEBDAV_NS, DISPLAYNAME, WEBDAV_PREFIX + ":" + DISPLAYNAME); + } + + public static void writeGetLastModified(Date lastModified, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, GETLASTMODIFIED, WEBDAV_PREFIX + ":" + GETLASTMODIFIED, attributes); + DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); + String dateFormatted = dateFormat.format(lastModified); + contentHandler.characters(dateFormatted.toCharArray(), 0, dateFormatted.length()); + contentHandler.endElement(WEBDAV_NS, GETLASTMODIFIED, WEBDAV_PREFIX + ":" + GETLASTMODIFIED); + } + + public static void writeCreationDate(Date creationDate, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, CREATIONDATE, WEBDAV_PREFIX + ":" + CREATIONDATE, attributes); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + String dateFormatted = dateFormat.format(creationDate); + contentHandler.characters(dateFormatted.toCharArray(), 0, dateFormatted.length()); + contentHandler.endElement(WEBDAV_NS, CREATIONDATE, WEBDAV_PREFIX + ":" + CREATIONDATE); + } + + public static void writeResourceType(boolean isCollection, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, RESOURCETYPE, WEBDAV_PREFIX + ":" + RESOURCETYPE, attributes); + if (isCollection) { + contentHandler.startElement(WEBDAV_NS, COLLECTION, WEBDAV_PREFIX + ":" + COLLECTION, attributes); + contentHandler.endElement(WEBDAV_NS, COLLECTION, WEBDAV_PREFIX + ":" + COLLECTION); + } + contentHandler.endElement(WEBDAV_NS, RESOURCETYPE, WEBDAV_PREFIX + ":" + RESOURCETYPE); + } + + public static void writeGetContentType(String getContentType, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, GETCONTENTTYPE, WEBDAV_PREFIX + ":" + GETCONTENTTYPE, attributes); + contentHandler.characters(getContentType.toCharArray(), 0, getContentType.length()); + contentHandler.endElement(WEBDAV_NS, GETCONTENTTYPE, WEBDAV_PREFIX + ":" + GETCONTENTTYPE); + } + + public static void writeGetContentLength(String getContentLength, ContentHandler contentHandler, + Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, GETCONTENTLENGTH, WEBDAV_PREFIX + ":" + GETCONTENTLENGTH, attributes); + contentHandler.characters(getContentLength.toCharArray(), 0, getContentLength.length()); + contentHandler.endElement(WEBDAV_NS, GETCONTENTLENGTH, WEBDAV_PREFIX + ":" + GETCONTENTLENGTH); + } + + public static void writeSupportedLock(boolean supportsExclusive, boolean supportsShared, + ContentHandler contentHandler, Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, SUPPORTEDLOCK, WEBDAV_PREFIX + ":" + SUPPORTEDLOCK, attributes); + if (supportsExclusive) { + contentHandler.startElement(WEBDAV_NS, LOCKENTRY, WEBDAV_PREFIX + ":" + LOCKENTRY, attributes); + contentHandler.startElement(WEBDAV_NS, LOCKSCOPE, WEBDAV_PREFIX + ":" + LOCKSCOPE, attributes); + contentHandler.startElement(WEBDAV_NS, EXCLUSIVE, WEBDAV_PREFIX + ":" + EXCLUSIVE, attributes); + contentHandler.endElement(WEBDAV_NS, EXCLUSIVE, WEBDAV_PREFIX + ":" + EXCLUSIVE); + contentHandler.endElement(WEBDAV_NS, LOCKSCOPE, WEBDAV_PREFIX + ":" + LOCKSCOPE); + contentHandler.startElement(WEBDAV_NS, LOCKTYPE, WEBDAV_PREFIX + ":" + LOCKTYPE, attributes); + contentHandler.startElement(WEBDAV_NS, WRITE, WEBDAV_PREFIX + ":" + WRITE, attributes); + contentHandler.endElement(WEBDAV_NS, WRITE, WEBDAV_PREFIX + ":" + WRITE); + contentHandler.endElement(WEBDAV_NS, LOCKTYPE, WEBDAV_PREFIX + ":" + LOCKTYPE); + contentHandler.endElement(WEBDAV_NS, LOCKENTRY, WEBDAV_PREFIX + ":" + LOCKENTRY); + } + if (supportsShared) { + contentHandler.startElement(WEBDAV_NS, LOCKENTRY, WEBDAV_PREFIX + ":" + LOCKENTRY, attributes); + contentHandler.startElement(WEBDAV_NS, LOCKSCOPE, WEBDAV_PREFIX + ":" + LOCKSCOPE, attributes); + contentHandler.startElement(WEBDAV_NS, SHARED, WEBDAV_PREFIX + ":" + SHARED, attributes); + contentHandler.endElement(WEBDAV_NS, SHARED, WEBDAV_PREFIX + ":" + SHARED); + contentHandler.endElement(WEBDAV_NS, LOCKSCOPE, WEBDAV_PREFIX + ":" + LOCKSCOPE); + contentHandler.startElement(WEBDAV_NS, LOCKTYPE, WEBDAV_PREFIX + ":" + LOCKTYPE, attributes); + contentHandler.startElement(WEBDAV_NS, WRITE, WEBDAV_PREFIX + ":" + WRITE, attributes); + contentHandler.endElement(WEBDAV_NS, WRITE, WEBDAV_PREFIX + ":" + WRITE); + contentHandler.endElement(WEBDAV_NS, LOCKTYPE, WEBDAV_PREFIX + ":" + LOCKTYPE); + contentHandler.endElement(WEBDAV_NS, LOCKENTRY, WEBDAV_PREFIX + ":" + LOCKENTRY); + } + contentHandler.endElement(WEBDAV_NS, SUPPORTEDLOCK, WEBDAV_PREFIX + ":" + SUPPORTEDLOCK); + } + + public static void writeLockDiscovery(ContentHandler contentHandler, Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, LOCKDISCOVERY, WEBDAV_PREFIX + ":" + LOCKDISCOVERY, attributes); + contentHandler.endElement(WEBDAV_NS, LOCKDISCOVERY, WEBDAV_PREFIX + ":" + LOCKDISCOVERY); + } + + public static void writeLockDiscovery(String lockType, String lockScope, String depth, + String owner, String timeout, String lockToken, + ContentHandler contentHandler, Attributes attributes) + throws SAXException + { + contentHandler.startElement(WEBDAV_NS, LOCKDISCOVERY, WEBDAV_PREFIX + ":" + LOCKDISCOVERY, attributes); + contentHandler.startElement(WEBDAV_NS, ACTIVELOCK, WEBDAV_PREFIX + ":" + ACTIVELOCK, attributes); + contentHandler.startElement(WEBDAV_NS, LOCKTYPE, WEBDAV_PREFIX + ":" + LOCKTYPE, attributes); + contentHandler.startElement(WEBDAV_NS, lockType, WEBDAV_PREFIX + ":" + lockType, attributes); + contentHandler.endElement(WEBDAV_NS, lockType, WEBDAV_PREFIX + ":" + lockType); + contentHandler.endElement(WEBDAV_NS, LOCKTYPE, WEBDAV_PREFIX + ":" + LOCKTYPE); + contentHandler.startElement(WEBDAV_NS, LOCKSCOPE, WEBDAV_PREFIX + ":" + LOCKSCOPE, attributes); + contentHandler.startElement(WEBDAV_NS, lockScope, WEBDAV_PREFIX + ":" + lockScope, attributes); + contentHandler.endElement(WEBDAV_NS, lockScope, WEBDAV_PREFIX + ":" + lockScope); + contentHandler.endElement(WEBDAV_NS, LOCKSCOPE, WEBDAV_PREFIX + ":" + LOCKSCOPE); + contentHandler.startElement(WEBDAV_NS, DEPTH, WEBDAV_PREFIX + ":" + DEPTH, attributes); + contentHandler.characters(depth.toCharArray(), 0, depth.length()); + contentHandler.endElement(WEBDAV_NS, DEPTH, WEBDAV_PREFIX + ":" + DEPTH); + contentHandler.startElement(WEBDAV_NS, OWNER, WEBDAV_PREFIX + ":" + OWNER, attributes); + contentHandler.characters(owner.toCharArray(), 0, owner.length()); + contentHandler.endElement(WEBDAV_NS, OWNER, WEBDAV_PREFIX + ":" + OWNER); + contentHandler.startElement(WEBDAV_NS, TIMEOUT, WEBDAV_PREFIX + ":" + TIMEOUT, attributes); + contentHandler.characters(timeout.toCharArray(), 0, timeout.length()); + contentHandler.endElement(WEBDAV_NS, TIMEOUT, WEBDAV_PREFIX + ":" + TIMEOUT); + contentHandler.startElement(WEBDAV_NS, LOCKTOKEN, WEBDAV_PREFIX + ":" + LOCKTOKEN, attributes); + contentHandler.startElement(WEBDAV_NS, HREF, WEBDAV_PREFIX + ":" + HREF, attributes); + contentHandler.characters(lockToken.toCharArray(), 0, lockToken.length()); + contentHandler.endElement(WEBDAV_NS, HREF, WEBDAV_PREFIX + ":" + HREF); + contentHandler.endElement(WEBDAV_NS, LOCKTOKEN, WEBDAV_PREFIX + ":" + LOCKTOKEN); + contentHandler.endElement(WEBDAV_NS, ACTIVELOCK, WEBDAV_PREFIX + ":" + ACTIVELOCK); + contentHandler.endElement(WEBDAV_NS, LOCKDISCOVERY, WEBDAV_PREFIX + ":" + LOCKDISCOVERY); + } +} Eigenschaftsänderungen: src/modules/webdav2/java/src/org/apache/lenya/cms/webdav/WebDAVXmlHelper.java ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/webdav2/sitemap.xmap =================================================================== --- src/modules/webdav2/sitemap.xmap (Revision 0) +++ src/modules/webdav2/sitemap.xmap (Revision 0) @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + utf-8 + yes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Eigenschaftsänderungen: src/modules/webdav2/sitemap.xmap ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: src/modules/webdav2/xslt/init.xsl =================================================================== --- src/modules/webdav2/xslt/init.xsl (Revision 0) +++ src/modules/webdav2/xslt/init.xsl (Revision 0) @@ -0,0 +1,60 @@ + + + + + + + + + // + + + + + + + + + + + + + + httpd/unix-directory + + 0 + + + HTTP/1.1 200 OK + + + + + //webdav + + + + webdav + + + + + + + + + + httpd/unix-directory + + 0 + + + HTTP/1.1 200 OK + + + + + + + + Eigenschaftsänderungen: src/modules/webdav2/xslt/init.xsl ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: src/modules/webdav2/content/401-unauthorized.xhtml =================================================================== --- src/modules/webdav2/content/401-unauthorized.xhtml (Revision 0) +++ src/modules/webdav2/content/401-unauthorized.xhtml (Revision 0) @@ -0,0 +1,6 @@ + +401 Unauthorized + +401 Unauthorized + + Eigenschaftsänderungen: src/modules/webdav2/content/401-unauthorized.xhtml ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: src/modules/webdav2/usecases/webdav.js =================================================================== --- src/modules/webdav2/usecases/webdav.js (Revision 0) +++ src/modules/webdav2/usecases/webdav.js (Revision 0) @@ -0,0 +1,281 @@ +/* +* Copyright 1999-2004 The Apache Software Foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* Helper method to add all request parameters to a usecase */ +function passRequestParameters(flowHelper, usecase) { + var names = cocoon.request.getParameterNames(); + while (names.hasMoreElements()) { + var name = names.nextElement(); + if (!name.equals("lenya.usecase") + && !name.equals("lenya.continuation") + && !name.equals("submit")) { + + var value = flowHelper.getRequest(cocoon).get(name); + + var string = new Packages.java.lang.String(); + if (string.getClass().isInstance(value)) { + usecase.setParameter(name, value); + } + else { + usecase.setPart(name, value); + } + + } + } +} + +/* Helper method to add all request headers to a usecase */ +function passRequestHeaders(flowHelper, usecase) { + var names = cocoon.request.getHeaderNames(); + while (names.hasMoreElements()) { + var name = names.nextElement(); + var value = flowHelper.getRequest(cocoon).getHeader(name); + + var string = new Packages.java.lang.String(); + if (string.getClass().isInstance(value)) { + usecase.setParameter("header-"+name, value); + } + else { + usecase.setPart("header-"+name, value); + } + } +} + +function sendStatus(sc) { + cocoon.sendStatus(sc); +} + +function httpGet() { +} + +function httpMkcol() { + // MKCOL method not supported. + sendStatus(403); +} + +function httpPut() { + var status = executeUsecase("webdav.put"); + if(status) + sendStatus(204); + else { + sendStatus(415); + } +} + +function httpDelete() { + var status = executeUsecase("webdav.delete"); + sendStatus(200); +} + +function httpOptions() { + cocoon.response.setHeader("DAV","1"); + var options = "OPTIONS,GET,PUT,LOCK,PROPFIND,DELETE"; +// var options = "OPTIONS,GET,HEAD,POST,DELETE,TRACE,PUT,LOCK" +// + ",MKCOL,PROPFIND,PROPPATCH,COPY,MOVE"; + cocoon.response.setHeader("Allow",options); + + //interoperability with Windows 2000 + var w2kDAVDiscoverAgent = "Microsoft Data Access Internet" + + " Publishing Provider Protocol Discovery"; + if (cocoon.request.getHeader("User-Agent") == w2kDAVDiscoverAgent) { + cocoon.response.setHeader("MS-Author-Via","DAV"); + } + + sendStatus(200); +} + +/* + * convert the overwrite header into a boolean type + */ +function isOverwrite(header) { + var overwrite = true; + if (header == 'F') { + overwrite = false; + } + return overwrite; +} + +function executeUsecase(usecaseName) { + var view; + var proxy; + var menu = "nomenu"; + + var usecaseResolver; + var usecase; + var sourceUrl; + + if (cocoon.log.isDebugEnabled()) + cocoon.log.debug("usecases.js::executeUsecase() called, parameter lenya.usecase = [" + usecaseName + "]"); + + try { + + var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper"); + var request = flowHelper.getRequest(cocoon); + sourceUrl = Packages.org.apache.lenya.util.ServletHelper.getWebappURI(request); + + usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver"); + usecase = usecaseResolver.resolve(sourceUrl, usecaseName); + usecase.setSourceURL(sourceUrl); + usecase.setName(usecaseName); + view = usecase.getView(); + + passRequestParameters(flowHelper, usecase); + passRequestHeaders(flowHelper, usecase); + usecase.checkPreconditions(); + usecase.lockInvolvedObjects(); + proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase); + } + finally { + /* done with usecase component, tell usecaseResolver to release it */ + if (usecaseResolver != null) { + if (usecase != null) { + usecaseResolver.release(usecase); + usecase = undefined; + } + cocoon.releaseComponent(usecaseResolver); + } + } + + var success = false; + //var targetUrl; + var form; + var scriptString; + var evalFunc; + var generic; + + /* + * If the usecase has a view, this means we want to display something + * to the user before proceeding. This also means the usecase consists + * several steps; repeated until the user chooses to submit or cancel. + * + * If the usecase does not have a view, it is simply executed. + */ + + if (view) { + var ready = false; + while (!ready) { + + try { + var templateUri = view.getTemplateURI(); + if (templateUri) { + var viewUri = "view/" + menu + "/" + view.getTemplateURI(); + if (cocoon.log.isDebugEnabled()) + cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", creating view, calling Cocoon with viewUri = [" + viewUri + "]"); + + cocoon.sendPageAndWait(viewUri, {"usecase" : proxy}); + + } + else { + var viewUri = view.getViewURI(); + cocoon.sendPage(viewUri); + return; + } + } + catch (exception) { + /* if an exception was thrown by the view, allow the usecase to rollback the transition */ + try { + usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver"); + usecase = usecaseResolver.resolve(sourceUrl, usecaseName); + proxy.setup(usecase); + usecase.cancel(); + throw exception; + } + finally { + if (usecaseResolver != null) { + if (usecase != null) { + usecaseResolver.release(usecase); + usecase = undefined; + } + cocoon.releaseComponent(usecaseResolver); + } + } + } + + if (cocoon.log.isDebugEnabled()) + cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", after view, now advancing in usecase"); + + try { + usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver"); + usecase = usecaseResolver.resolve(sourceUrl, usecaseName); + proxy.setup(usecase); + + passRequestParameters(flowHelper, usecase); + usecase.advance(); + + if (cocoon.request.getParameter("submit")) { + usecase.checkExecutionConditions(); + if (! usecase.hasErrors()) { + usecase.execute(); + if (! usecase.hasErrors()) { + usecase.checkPostconditions(); + if (! usecase.hasErrors()) { + ready = true; + success = true; + } + } + } + } + else if (cocoon.request.getParameter("cancel")) { + usecase.cancel(); + ready = true; + } + proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase); + } + catch (exception) { + /* allow usecase to rollback the transition */ + usecase.cancel(); + throw exception; + } + finally { + if (usecaseResolver != null) { + if (usecase != null) { + usecaseResolver.release(usecase); + usecase = undefined; + } + cocoon.releaseComponent(usecaseResolver); + } + } + } + } + else { + try { + usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver"); + usecase = usecaseResolver.resolve(sourceUrl, usecaseName); + proxy.setup(usecase); + + usecase.execute(); + if (! usecase.hasErrors()) { + usecase.checkPostconditions(); + if (! usecase.hasErrors()) { + success = true; + } + } + } + catch (exception) { + /* allow usecase to rollback the transition */ + usecase.cancel(); + throw exception; + } + finally { + usecaseResolver.release(usecase); + usecase = undefined; + cocoon.releaseComponent(usecaseResolver); + } + } + + return success; + +} Eigenschaftsänderungen: src/modules/webdav2/usecases/webdav.js ___________________________________________________________________ Name: svn:eol-style + native Index: src/modules/xhtml/sitemap.xmap =================================================================== --- src/modules/xhtml/sitemap.xmap (Revision 387571) +++ src/modules/xhtml/sitemap.xmap (Arbeitskopie) @@ -69,6 +69,23 @@ + + + + + + + + + + + + + + + + + @@ -78,16 +95,11 @@ + - - - - - - - + Index: src/modules/opendocument/sitemap.xmap =================================================================== --- src/modules/opendocument/sitemap.xmap (Revision 387571) +++ src/modules/opendocument/sitemap.xmap (Arbeitskopie) @@ -35,6 +35,19 @@ + + + + + + + + + + + + + @@ -43,27 +56,24 @@ + - - - - + +--> Index: src/pubs/default/content/authoring/links/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/links/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/links/index_en.xml.meta (Arbeitskopie) @@ -24,6 +24,20 @@ Lenya links Lenya Development Team + Lenya Links + Links to Lenya resources. + Apache Software Foundation + + 2005-01-31 + + application/xml + + + de + + + Alle Rechte vorbehalten + Index: src/pubs/default/content/authoring/tutorial/new_doctype/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/tutorial/new_doctype/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/tutorial/new_doctype/index_en.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml en @@ -39,4 +39,4 @@ All rights reserved - \ No newline at end of file + Index: src/pubs/default/content/authoring/tutorial/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/tutorial/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/tutorial/index_de.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml de @@ -39,4 +39,4 @@ Alle Rechte vorbehalten - \ No newline at end of file + Index: src/pubs/default/content/authoring/tutorial/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/tutorial/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/tutorial/index_en.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml en @@ -39,4 +39,4 @@ All rights reserved - \ No newline at end of file + Index: src/pubs/default/content/authoring/index/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/index/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/index/index_de.xml.meta (Arbeitskopie) @@ -33,7 +33,7 @@ 2005-01-31 - + application/xhtml+xml de Index: src/pubs/default/content/authoring/index/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/index/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/index/index_en.xml.meta (Arbeitskopie) @@ -33,7 +33,7 @@ 2005-01-31 - + application/xhtml+xml en Index: src/pubs/default/content/authoring/doctypes/links/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/links/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/links/index_en.xml.meta (Arbeitskopie) @@ -6,6 +6,7 @@ lenya +application/xhtml+xml 2005-10-02 12:50:27 en Index: src/pubs/default/content/authoring/doctypes/opendocument/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/opendocument/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/opendocument/index_de.xml.meta (Arbeitskopie) @@ -5,6 +5,7 @@ OpenDocument lenya de + application/vnd.oasis.opendocument.text Index: src/pubs/default/content/authoring/doctypes/opendocument/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/opendocument/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/opendocument/index_en.xml.meta (Arbeitskopie) @@ -5,6 +5,7 @@ OpenDocument lenya en + application/vnd.oasis.opendocument.text Index: src/pubs/default/content/authoring/doctypes/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/index_de.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml de Index: src/pubs/default/content/authoring/doctypes/xhtml-document/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/xhtml-document/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/xhtml-document/index_de.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml de Index: src/pubs/default/content/authoring/doctypes/xhtml-document/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/xhtml-document/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/xhtml-document/index_en.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml en Index: src/pubs/default/content/authoring/doctypes/cforms/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/cforms/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/cforms/index_en.xml.meta (Arbeitskopie) @@ -9,6 +9,7 @@ 2005-10-13 11:19:30 en +application/xml cforms Index: src/pubs/default/content/authoring/doctypes/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/doctypes/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/doctypes/index_en.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml en Index: src/pubs/default/content/authoring/concepts/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/concepts/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/concepts/index_de.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml de Index: src/pubs/default/content/authoring/concepts/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/concepts/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/concepts/index_en.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml en Index: src/pubs/default/content/authoring/features/index_de.xml.meta =================================================================== --- src/pubs/default/content/authoring/features/index_de.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/features/index_de.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml de Index: src/pubs/default/content/authoring/features/index_en.xml.meta =================================================================== --- src/pubs/default/content/authoring/features/index_en.xml.meta (Revision 387571) +++ src/pubs/default/content/authoring/features/index_en.xml.meta (Arbeitskopie) @@ -30,7 +30,7 @@ 2005-01-31 - + application/xhtml+xml en Index: src/webapp/global-sitemap.xmap =================================================================== --- src/webapp/global-sitemap.xmap (Revision 387571) +++ src/webapp/global-sitemap.xmap (Arbeitskopie) @@ -325,6 +325,11 @@ + + + + + Index: src/webapp/lenya/config/sitemap/pipelines.xmap =================================================================== --- src/webapp/lenya/config/sitemap/pipelines.xmap (Revision 387571) +++ src/webapp/lenya/config/sitemap/pipelines.xmap (Arbeitskopie) @@ -61,13 +61,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -78,7 +107,7 @@ - +