Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ZipHandler.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ZipHandler.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ZipHandler.java (Arbeitskopie) @@ -153,7 +153,7 @@ if (contentNode.hasProperty(JcrConstants.JCR_MIMETYPE)) { mimeType = contentNode.getProperty(JcrConstants.JCR_MIMETYPE).getString(); } else { - mimeType = context.getMimeResolver().getMimeType(context.getExportRoot().getName()); + mimeType = detect(context.getExportRoot().getName()); } } catch (RepositoryException e) { // ignore and return false @@ -283,7 +283,8 @@ private final ZipEntry entry; private ZipEntryImportContext(ImportContext context, ZipEntry entry, BoundedInputStream bin, Node contentNode) throws IOException, RepositoryException { - super(contentNode, Text.getName(makeValidJCRPath(entry.getName(), true)), bin, context.getIOListener(), context.getMimeResolver()); + super(contentNode, Text.getName(makeValidJCRPath(entry.getName(), true)), + null, bin, context.getIOListener(), getIOManager().getDetector()); this.entry = entry; String path = makeValidJCRPath(entry.getName(), true); importRoot = IOUtil.mkDirs(contentNode, Text.getRelativeParent(path, 1), getCollectionNodeType()); @@ -312,7 +313,7 @@ private OutputStream out; private ZipEntryExportContext(Item exportRoot, OutputStream out, ExportContext context, int pos) { - super(exportRoot, out != null, context.getIOListener(), context.getMimeResolver()); + super(exportRoot, out != null, context.getIOListener()); this.out = out; try { String entryPath = (exportRoot.getPath().length() > pos) ? exportRoot.getPath().substring(pos) : ""; Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ImportContextImpl.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ImportContextImpl.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ImportContextImpl.java (Arbeitskopie) @@ -17,10 +17,15 @@ package org.apache.jackrabbit.server.io; import org.apache.jackrabbit.webdav.io.InputContext; +import org.apache.tika.detect.Detector; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.mime.MediaType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Item; + +import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -38,45 +43,13 @@ private final Item importRoot; private final String systemId; private final File inputFile; - private final MimeResolver mimeResolver; private InputContext inputCtx; private boolean completed; - /** - * Creates a new item import context with the given root item and the - * specified InputContext. If the input context provides an - * input stream, the stream is written to a temporary file in order to avoid - * problems with multiple IOHandlers that try to run the import but fail. - * The temporary file is deleted as soon as this context is informed that - * the import has been completed and it will not be used any more. - * - * @param importRoot the import root node - * @param systemId - * @param inputCtx wrapped by this ImportContext - */ - public ImportContextImpl(Item importRoot, String systemId, InputContext inputCtx) throws IOException { - this(importRoot, systemId, inputCtx, null); - } + private final Detector detector; - /** - * Creates a new item import context with the given root item and the - * specified InputContext. If the input context provides an - * input stream, the stream is written to a temporary file in order to avoid - * problems with multiple IOHandlers that try to run the import but fail. - * The temporary file is deleted as soon as this context is informed that - * the import has been completed and it will not be used any more. - * - * @param importRoot the import root node - * @param systemId - * @param inputCtx wrapped by this ImportContext - * @param mimeResolver - */ - public ImportContextImpl(Item importRoot, String systemId, InputContext inputCtx, - MimeResolver mimeResolver) throws IOException { - this(importRoot, systemId, (inputCtx != null) ? inputCtx.getInputStream() : null, null, mimeResolver); - this.inputCtx = inputCtx; - } + private final MediaType type; /** * Creates a new item import context. The specified InputStream is written @@ -87,39 +60,35 @@ * * @param importRoot * @param systemId - * @param in + * @param inputCtx input context, or null + * @param stream document input stream, or null * @param ioListener + * @param detector content type detector * @throws IOException * @see ImportContext#informCompleted(boolean) */ - public ImportContextImpl(Item importRoot, String systemId, InputStream in, - IOListener ioListener) throws IOException { - this(importRoot, systemId, in, ioListener, null); - } - - /** - * Creates a new item import context. The specified InputStream is written - * to a temporary file in order to avoid problems with multiple IOHandlers - * that try to run the import but fail. The temporary file is deleted as soon - * as this context is informed that the import has been completed and it - * will not be used any more. - * - * @param importRoot - * @param systemId - * @param in - * @param ioListener - * @param mimeResolver - * @throws IOException - * @see ImportContext#informCompleted(boolean) - */ - public ImportContextImpl(Item importRoot, String systemId, InputStream in, - IOListener ioListener, MimeResolver mimeResolver) + public ImportContextImpl( + Item importRoot, String systemId, InputContext inputCtx, + InputStream stream, IOListener ioListener, Detector detector) throws IOException { this.importRoot = importRoot; this.systemId = systemId; - this.inputFile = IOUtil.getTempFile(in); + this.inputCtx = inputCtx; this.ioListener = (ioListener != null) ? ioListener : new DefaultIOListener(log); - this.mimeResolver = (mimeResolver == null) ? IOUtil.MIME_RESOLVER : mimeResolver; + + Metadata metadata = new Metadata(); + if (inputCtx != null && inputCtx.getContentType() != null) { + metadata.set(Metadata.CONTENT_TYPE, inputCtx.getContentType()); + } + if (systemId != null) { + metadata.set(Metadata.RESOURCE_NAME_KEY, systemId); + } + if (stream != null && !stream.markSupported()) { + stream = new BufferedInputStream(stream); + } + this.detector = detector; + this.type = detector.detect(stream, metadata); + this.inputFile = IOUtil.getTempFile(stream); } /** @@ -137,10 +106,10 @@ } /** - * @see ImportContext#getImportRoot() + * @see ImportContext#getDetector() */ - public MimeResolver getMimeResolver() { - return mimeResolver; + public Detector getDetector() { + return detector; } /** @@ -210,34 +179,17 @@ } /** - * @return the content type present on the InputContext or - * null - * @see InputContext#getContentType() - */ - private String getContentType() { - return (inputCtx != null) ? inputCtx.getContentType() : null; - } - - /** * @see ImportContext#getMimeType() */ public String getMimeType() { - String contentType = getContentType(); - String mimeType = null; - if (contentType != null) { - mimeType = IOUtil.getMimeType(contentType); - } else if (getSystemId() != null) { - mimeType = mimeResolver.getMimeType(getSystemId()); - } - return mimeType; + return IOUtil.getMimeType(type.toString()); } /** * @see ImportContext#getEncoding() */ public String getEncoding() { - String contentType = getContentType(); - return (contentType != null) ? IOUtil.getEncoding(contentType) : null; + return IOUtil.getEncoding(type.toString()); } /** Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOManager.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOManager.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOManager.java (Arbeitskopie) @@ -17,6 +17,7 @@ package org.apache.jackrabbit.server.io; import org.apache.jackrabbit.webdav.DavResource; +import org.apache.tika.detect.Detector; import java.io.IOException; @@ -41,6 +42,20 @@ public IOHandler[] getIOHandlers(); /** + * Return the configured type detector. + * + * @return content type detector + */ + Detector getDetector(); + + /** + * Sets the configured type detector. + * + * @param detector content type detector. + */ + void setDetector(Detector detector); + + /** * Passes the specified context and boolean value to the IOHandlers present * on this manager. * As soon as the first handler incidates success the import should be Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOUtil.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOUtil.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOUtil.java (Arbeitskopie) @@ -49,12 +49,6 @@ public static final long UNDEFINED_LENGTH = -1; /** - * MimeType resolver used to retrieve the mimetype if no content type is - * available during import. - */ - public static final MimeResolver MIME_RESOLVER = new MimeResolver(); - - /** * Return the last modification time as formatted string. * * @return last modification time as string. Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultIOManager.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultIOManager.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultIOManager.java (Arbeitskopie) @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.server.io; +import org.apache.tika.detect.Detector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ExportContextImpl.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ExportContextImpl.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ExportContextImpl.java (Arbeitskopie) @@ -19,6 +19,7 @@ import org.apache.jackrabbit.webdav.DavConstants; import org.apache.jackrabbit.webdav.DavResource; import org.apache.jackrabbit.webdav.io.OutputContext; +import org.apache.tika.detect.Detector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,13 +54,9 @@ private File outFile; private OutputStream outStream; - public ExportContextImpl(Item exportRoot, OutputContext outputCtx) throws IOException { - this(exportRoot, outputCtx, null); - } - - public ExportContextImpl(Item exportRoot, OutputContext outputCtx, - MimeResolver mimeResolver) throws IOException { - super(exportRoot, (outputCtx != null) ? outputCtx.hasStream() : false, null, mimeResolver); + public ExportContextImpl(Item exportRoot, OutputContext outputCtx) + throws IOException { + super(exportRoot, outputCtx != null && outputCtx.hasStream(), null); this.outputCtx = outputCtx; if (hasStream()) { // we need a tmp file, since the export could fail Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/MimeResolver.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/MimeResolver.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/MimeResolver.java (Arbeitskopie) @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jackrabbit.server.io; - -import org.apache.jackrabbit.util.Text; - -import java.io.IOException; -import java.util.Properties; - -/** - * This Class implements a very simple mime type resolver. - */ -public class MimeResolver { - - /** - * the loaded mimetypes - */ - private Properties mimeTypes = new Properties(); - - /** - * the default mimetype - */ - private String defaultMimeType = "application/octet-stream"; - - /** - * Creates a new mimetype resolver containing the default mappings and having - * "application/octet-stream" set as default mimetype. - */ - public MimeResolver() { - try { - // init the mime types - mimeTypes.load(getClass().getResourceAsStream("mimetypes.properties")); - } catch (IOException e) { - throw new InternalError("Unable to load mimetypes: " + e.toString()); - } - } - - /** - * Creates a new mime type resolver extending the default mapping by the - * entries of the given Properties. The default mimetype is set to the - * given defaultMimeType. - * - * @param additionalProperties MimeType mappings to be added to the default - * properties. - * @param defaultMimeType The default mimetype. A non-null String with a - * length greater than 0. - */ - public MimeResolver(Properties additionalProperties, String defaultMimeType) { - // init default mimetypes. - this(); - // extend or adjust mapping. - if (additionalProperties != null && !additionalProperties.isEmpty()) { - mimeTypes.putAll(additionalProperties); - } - // set the default type. - if (defaultMimeType != null && defaultMimeType.length() > 0) { - this.defaultMimeType = defaultMimeType; - } - } - - /** - * Returns the default mime type - * @return - */ - public String getDefaultMimeType() { - return defaultMimeType; - } - - /** - * Sets the default mime type - * @param defaultMimeType - */ - public void setDefaultMimeType(String defaultMimeType) { - this.defaultMimeType = defaultMimeType; - } - - /** - * Retrusn the mime type for the given name. - * @param filename - * @return - */ - public String getMimeType(String filename) { - String ext = Text.getName(filename, '.'); - if (ext.equals("")) { - ext = filename; - } - return mimeTypes.getProperty(ext.toLowerCase(), defaultMimeType); - } -} Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/AbstractExportContext.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/AbstractExportContext.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/AbstractExportContext.java (Arbeitskopie) @@ -32,21 +32,14 @@ private final IOListener ioListener; private final Item exportRoot; private final boolean hasStream; - private final MimeResolver mimeResolver; protected boolean completed; - public AbstractExportContext(Item exportRoot, boolean hasStream, - IOListener ioListener) { - this(exportRoot, hasStream, ioListener, null); - } - - public AbstractExportContext(Item exportRoot, boolean hasStream, - IOListener ioListener, MimeResolver mimeResolver) { + public AbstractExportContext( + Item exportRoot, boolean hasStream, IOListener ioListener) { this.exportRoot = exportRoot; this.hasStream = hasStream; this.ioListener = (ioListener != null) ? ioListener : new DefaultIOListener(log); - this.mimeResolver = (mimeResolver != null) ? mimeResolver : IOUtil.MIME_RESOLVER; } public IOListener getIOListener() { @@ -57,10 +50,6 @@ return exportRoot; } - public MimeResolver getMimeResolver() { - return mimeResolver; - } - public boolean hasStream() { return hasStream; } Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ImportContext.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ImportContext.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ImportContext.java (Arbeitskopie) @@ -17,6 +17,9 @@ package org.apache.jackrabbit.server.io; import javax.jcr.Item; + +import org.apache.tika.detect.Detector; + import java.io.InputStream; /** @@ -33,13 +36,6 @@ public Item getImportRoot(); /** - * Return the MimeResolver defined for this import context. - * - * @return mimetype resolver defined for this import context. - */ - public MimeResolver getMimeResolver(); - - /** * Returns the system id of the resource to be imported. This id depends on * the system the resource is comming from. it can be a filename, a * display name of a webdav resource, an URI, etc. Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/DefaultHandler.java (Arbeitskopie) @@ -24,6 +24,10 @@ import org.apache.jackrabbit.webdav.xml.Namespace; import org.apache.jackrabbit.webdav.property.DavPropertyName; import org.apache.jackrabbit.webdav.property.DavProperty; +import org.apache.tika.config.TikaConfig; +import org.apache.tika.detect.Detector; +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,21 +74,26 @@ private static Logger log = LoggerFactory.getLogger(DefaultHandler.class); - private String collectionNodetype = JcrConstants.NT_FOLDER; - private String defaultNodetype = JcrConstants.NT_FILE; - /* IMPORTANT NOTE: for webDAV compliance the default nodetype of the content - node has been changed from nt:resource to nt:unstructured. */ - private String contentNodetype = JcrConstants.NT_UNSTRUCTURED; + private String collectionNodetype; + private String defaultNodetype; + + private String contentNodetype; + private IOManager ioManager; /** - * Creates a new DefaultHandler with default nodetype definitions - * and without setting the IOManager. + * Creates a new DefaultHandler with default nodetype definitions:
+ * * - * @see IOHandler#setIOManager(IOManager) + * @param ioManager the I/O manager */ public DefaultHandler() { + this(null); } /** @@ -98,7 +107,13 @@ * @param ioManager the I/O manager */ public DefaultHandler(IOManager ioManager) { - this.ioManager = ioManager; + this(ioManager, + JcrConstants.NT_FOLDER, + JcrConstants.NT_FILE, + // IMPORTANT NOTE: for webDAV compliance the default type + // of the content node has been changed from nt:resource to + // nt:unstructured + JcrConstants.NT_UNSTRUCTURED); } /** @@ -640,6 +655,24 @@ return failures; } + /** + * Detects the media type of a document based on the given name. + * + * @param name document name + * @return detected content type (or application/octet-stream) + */ + protected String detect(String name) { + try { + Metadata metadata = new Metadata(); + metadata.set(Metadata.RESOURCE_NAME_KEY, name); + return ioManager.getDetector().detect(null, metadata).toString(); + } catch (IOException e) { + // Can not happen since the InputStream above is null + throw new IllegalStateException( + "Unexpected IOException", e); + } + } + //------------------------------------------------------------< private >--- /** * Builds a webdav property name from the given jcrName. In case the jcrName Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOManagerImpl.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOManagerImpl.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/IOManagerImpl.java (Arbeitskopie) @@ -16,14 +16,15 @@ */ package org.apache.jackrabbit.server.io; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.jackrabbit.webdav.DavResource; +import org.apache.tika.detect.Detector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.jackrabbit.webdav.DavResource; -import java.io.IOException; -import java.util.List; -import java.util.ArrayList; - /** * IOManagerImpl represents the most simple IOManager * implementation that provides a default constructor and does define any @@ -33,6 +34,11 @@ private static Logger log = LoggerFactory.getLogger(IOManagerImpl.class); + /** + * Content type detector. + */ + private Detector detector; + private final List ioHandlers = new ArrayList(); /** @@ -64,6 +70,24 @@ } /** + * Return the configured type detector. + * + * @return content type detector + */ + public Detector getDetector() { + return detector; + } + + /** + * Sets the configured type detector. + * + * @param detector content type detector + */ + public void setDetector(Detector detector) { + this.detector = detector; + } + + /** * @see IOManager#importContent(ImportContext, boolean) */ public boolean importContent(ImportContext context, boolean isCollection) throws IOException { Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ExportContext.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ExportContext.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/ExportContext.java (Arbeitskopie) @@ -17,6 +17,7 @@ package org.apache.jackrabbit.server.io; import javax.jcr.Item; + import java.io.OutputStream; /** @@ -39,13 +40,6 @@ public OutputStream getOutputStream(); /** - * Return the MimeResolver defined for this export context. - * - * @return mimetype resolver defined for this export context. - */ - public MimeResolver getMimeResolver(); - - /** * Set the content type for the resource content * * @param mimeType Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/XmlHandler.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/XmlHandler.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/io/XmlHandler.java (Arbeitskopie) @@ -149,7 +149,7 @@ if (contentNode.hasProperty(JcrConstants.JCR_MIMETYPE)) { mimeType = contentNode.getProperty(JcrConstants.JCR_MIMETYPE).getString(); } else { - mimeType = context.getMimeResolver().getMimeType(context.getExportRoot().getName()); + mimeType = detect(context.getExportRoot().getName()); } } catch (RepositoryException e) { // ignore and return false Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceFactoryImpl.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceFactoryImpl.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceFactoryImpl.java (Arbeitskopie) @@ -50,17 +50,6 @@ /** * Create a new ResourceFactory that uses the given lock - * manager and the default {@link ResourceConfig resource config}. - * - * @param lockMgr - */ - public ResourceFactoryImpl(LockManager lockMgr) { - this.lockMgr = lockMgr; - this.resourceConfig = new ResourceConfig(); - } - - /** - * Create a new ResourceFactory that uses the given lock * manager and resource filter. * * @param lockMgr @@ -68,7 +57,7 @@ */ public ResourceFactoryImpl(LockManager lockMgr, ResourceConfig resourceConfig) { this.lockMgr = lockMgr; - this.resourceConfig = (resourceConfig != null) ? resourceConfig : new ResourceConfig(); + this.resourceConfig = resourceConfig; } /** Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/DavResourceImpl.java (Arbeitskopie) @@ -897,7 +897,10 @@ * @throws IOException */ protected ImportContext getImportContext(InputContext inputCtx, String systemId) throws IOException { - return new ImportContextImpl(node, systemId, inputCtx, config.getMimeResolver()); + return new ImportContextImpl( + node, systemId, inputCtx, + (inputCtx != null) ? inputCtx.getInputStream() : null, + new DefaultIOListener(log), config.getDetector()); } /** @@ -908,7 +911,7 @@ * @throws IOException */ protected ExportContext getExportContext(OutputContext outputCtx) throws IOException { - return new ExportContextImpl(node, outputCtx, config.getMimeResolver()); + return new ExportContextImpl(node, outputCtx); } /** Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/SimpleWebdavServlet.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/SimpleWebdavServlet.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/SimpleWebdavServlet.java (Arbeitskopie) @@ -28,13 +28,19 @@ import org.apache.jackrabbit.webdav.lock.LockManager; import org.apache.jackrabbit.webdav.lock.SimpleLockManager; import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet; +import org.apache.tika.detect.Detector; +import org.apache.tika.mime.MimeTypeException; +import org.apache.tika.mime.MimeTypesFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Repository; import javax.servlet.ServletContext; import javax.servlet.ServletException; + +import java.io.IOException; import java.net.MalformedURLException; +import java.net.URL; /** * WebdavServlet provides webdav support (level 1 and 2 complient) for @@ -76,6 +82,13 @@ public static final String INIT_PARAM_RESOURCE_CONFIG = "resource-config"; /** + * Name of the parameter that specifies the servlet resource path of + * a custom <mime-info/> configuration file. The default setting + * is to use the MIME media type database included in Apache Tika. + */ + public static final String INIT_PARAM_MIME_INFO = "mime-info"; + + /** * Servlet context attribute used to store the path prefix instead of * having a static field with this servlet. The latter causes problems * when running multiple @@ -150,10 +163,10 @@ } log.info("WWW-Authenticate header = '" + authenticate_header + "'"); + config = new ResourceConfig(getDetector()); String configParam = getInitParameter(INIT_PARAM_RESOURCE_CONFIG); if (configParam != null) { try { - config = new ResourceConfig(); config.parse(getServletContext().getResource(configParam)); } catch (MalformedURLException e) { log.debug("Unable to build resource filter provider."); @@ -162,6 +175,40 @@ } /** + * Reads and returns the configured <mime-info/> database. + * + * @see #INIT_PARAM_MIME_INFO + * @return MIME media type database + * @throws ServletException if the database is invalid or can not be read + */ + private Detector getDetector() throws ServletException { + URL url; + + String mimeInfo = getInitParameter(INIT_PARAM_MIME_INFO); + if (mimeInfo != null) { + try { + url = getServletContext().getResource(mimeInfo); + } catch (MalformedURLException e) { + throw new ServletException( + "Invalid " + INIT_PARAM_MIME_INFO + + " configuration setting: " + mimeInfo, e); + } + } else { + url = MimeTypesFactory.class.getResource("tika-mimetypes.xml"); + } + + try { + return MimeTypesFactory.create(url); + } catch (MimeTypeException e) { + throw new ServletException( + "Invalid MIME media type database: " + url, e); + } catch (IOException e) { + throw new ServletException( + "Unable to read MIME media type database: " + url, e); + } + } + + /** * {@inheritDoc} */ protected boolean isPreconditionValid(WebdavRequest request, @@ -345,10 +392,6 @@ * @return the resource configuration. */ public ResourceConfig getResourceConfig() { - // fallback if no config present - if (config == null) { - config = new ResourceConfig(); - } return config; } Index: jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java =================================================================== --- jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java (Revision 819862) +++ jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java (Arbeitskopie) @@ -16,33 +16,33 @@ */ package org.apache.jackrabbit.webdav.simple; -import org.apache.jackrabbit.server.io.IOManager; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + import org.apache.jackrabbit.server.io.DefaultIOManager; import org.apache.jackrabbit.server.io.IOHandler; +import org.apache.jackrabbit.server.io.IOManager; +import org.apache.jackrabbit.server.io.PropertyHandler; import org.apache.jackrabbit.server.io.PropertyManager; -import org.apache.jackrabbit.server.io.PropertyHandler; import org.apache.jackrabbit.server.io.PropertyManagerImpl; -import org.apache.jackrabbit.server.io.MimeResolver; +import org.apache.jackrabbit.webdav.xml.DomUtil; import org.apache.jackrabbit.webdav.xml.ElementIterator; -import org.apache.jackrabbit.webdav.xml.DomUtil; +import org.apache.tika.detect.Detector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Document; import org.xml.sax.SAXException; -import javax.jcr.Item; -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; -import java.net.URL; -import java.util.List; -import java.util.ArrayList; -import java.util.Properties; -import java.io.IOException; -import java.io.InputStream; - /** * ResourceConfig... */ @@ -50,13 +50,21 @@ private static Logger log = LoggerFactory.getLogger(ResourceConfig.class); + /** + * Content type detector. + */ + private final Detector detector; + private ItemFilter itemFilter; private IOManager ioManager; private PropertyManager propManager; private String[] nodetypeNames = new String[0]; private boolean collectionNames = false; - private MimeResolver mimeResolver; + public ResourceConfig(Detector detector) { + this.detector = detector; + } + /** * Tries to parse the given xml configuration file. * The xml must match the following structure:
@@ -86,6 +94,11 @@ * > * <!ELEMENT defaultmimetype (CDATA) > * + *

+ * The <mimetypeproperties/> settings have been deprecated and will + * be ignored with a warning. Instead you can use the + * {@link SimpleWebdavServlet#INIT_PARAM_MIME_INFO mime-info} + * servlet initialization parameter to customize the media type settings. * * @param configURL */ @@ -107,6 +120,7 @@ Object inst = buildClassFromConfig(el); if (inst != null && inst instanceof IOManager) { ioManager = (IOManager)inst; + ioManager.setDetector(detector); // get optional 'iohandler' child elements and populate the // ioManager with the instances ElementIterator iohElements = DomUtil.getChildren(el, "iohandler", null); @@ -177,21 +191,11 @@ log.debug("Resource configuration: no 'filter' element specified."); } - // optional mimetype properties - Properties properties = new Properties(); - String defaultMimetype = null; el = DomUtil.getChildElement(config, "mimetypeproperties", null); if (el != null) { - defaultMimetype = DomUtil.getChildText(el, "defaultmimetype", null); - ElementIterator it = DomUtil.getChildren(el, "mimemapping", null); - while (it.hasNext()) { - Element mimeMapping = it.nextElement(); - String extension = DomUtil.getAttribute(mimeMapping, "extension", null); - String mimetype = DomUtil.getAttribute(mimeMapping, "mimetype", null); - properties.put(extension, mimetype); - } + log.warn("Ignoring deprecated mimetypeproperties settings: {}", + configURL); } - mimeResolver = new MimeResolver(properties, defaultMimetype); } catch (IOException e) { log.debug("Invalid resource configuration: " + e.getMessage()); } catch (ParserConfigurationException e) { @@ -270,6 +274,7 @@ if (ioManager == null) { log.debug("ResourceConfig: missing io-manager > building DefaultIOManager "); ioManager = new DefaultIOManager(); + ioManager.setDetector(detector); } return ioManager; } @@ -331,10 +336,12 @@ } /** + * Returns the configured content type detector. * - * @return + * @return content type detector */ - public MimeResolver getMimeResolver() { - return mimeResolver; + public Detector getDetector() { + return detector; } -} \ No newline at end of file + +} Index: jackrabbit-jcr-server/pom.xml =================================================================== --- jackrabbit-jcr-server/pom.xml (Revision 819862) +++ jackrabbit-jcr-server/pom.xml (Arbeitskopie) @@ -77,6 +77,11 @@ 2.0-SNAPSHOT + org.apache.tika + tika-core + 0.4 + + org.slf4j slf4j-api