You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xindice-dev@xml.apache.org by vg...@apache.org on 2007/05/25 03:43:43 UTC
svn commit: r541504 [2/7] - in /xml/xindice/trunk: ./ config/
java/scratchpad/webadmin/ java/src/org/apache/xindice/client/xmldb/embed/
java/src/org/apache/xindice/core/ java/src/org/apache/xindice/core/data/
java/src/org/apache/xindice/core/filer/ jav...
Modified: xml/xindice/trunk/java/src/org/apache/xindice/util/StringUtilities.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/util/StringUtilities.java?view=diff&rev=541504&r1=541503&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/util/StringUtilities.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/util/StringUtilities.java Thu May 24 18:43:39 2007
@@ -73,7 +73,7 @@
for (int i = sb.length(); i < width; i++) {
sb.append(' ');
}
-
+
if (sb.length() > width) {
sb.setLength(width);
}
@@ -94,7 +94,7 @@
for (int i = sb.length(); i < width; i++) {
sb.insert(0, ' ');
}
-
+
if (sb.length() > width) {
return sb.toString().substring(sb.length() - width);
} else {
@@ -162,7 +162,7 @@
public static int findWhiteSpace(String value, int start) {
char[] chars = value.toCharArray();
for (int i = start; i < chars.length; i++) {
- if (chars[i] <= 32) {
+ if (Character.isWhitespace(chars[i])) {
return i;
}
}
@@ -192,9 +192,8 @@
public static String javaEncode(String value) {
StringTokenizer st = new StringTokenizer(value, "\b\t\n\f\r\"\'\\", true);
StringBuffer sb = new StringBuffer(value.length());
- String token;
while (st.hasMoreTokens()) {
- token = st.nextToken();
+ String token = st.nextToken();
if (token.equals("\b")) {
sb.append("\\b");
} else if (token.equals("\t")) {
@@ -224,5 +223,69 @@
} else {
return s1.equals(s2);
}
+ }
+
+ /**
+ * Converts input text into its XML representation by escaping all special symbols,
+ * if any are present.
+ *
+ * @param text Input string
+ * @return String with all the special symbols escaped
+ */
+ public static String escapeXml(String text) {
+ char[] value = text.toCharArray();
+ StringBuffer buf = new StringBuffer();
+ int start = 0;
+ int len = 0;
+
+ for (int i = 0; i < value.length; i++) {
+ String outval = null;
+
+ switch (value[i]) {
+ case '&':
+ outval = "&";
+ break;
+ case '\'':
+ outval = "'";
+ break;
+ case '\"':
+ outval = """;
+ break;
+ case '<':
+ outval = "<";
+ break;
+ case '>':
+ outval = ">";
+ break;
+ default :
+ len++;
+ break;
+ }
+
+ if (outval != null) {
+ if (len > 0) {
+ buf.append(value, start, len);
+ }
+ buf.append(outval);
+ start = i + 1;
+ len = 0;
+ }
+ }
+
+ if (len > 0) {
+ buf.append(value, start, len);
+ }
+
+ return buf.toString();
+ }
+
+ public static boolean isBlank(String str) {
+ for (int i = 0; i < str.length(); i++) {
+ if (!Character.isWhitespace(str.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
}
}
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/Location.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/Location.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/Location.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/Location.java Thu May 24 18:43:39 2007
@@ -0,0 +1,126 @@
+/*
+ * 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.xindice.webadmin;
+
+import org.apache.xindice.core.Collection;
+import org.apache.xindice.core.DBException;
+import org.apache.xindice.core.Database;
+
+/**
+ * Helper class for parsing path information to get database, collection
+ * and resource name.
+ */
+public class Location {
+ private Collection collection;
+ private String name;
+ private boolean isRoot;
+
+ /**
+ * Create Location instance out of path information. There are several
+ * possible outcomes: <ul>
+ * <li>Path is empty or "/" - both collection and name are null, isRoot
+ * equals true;
+ * <li>Path matches some collection's canonical name - collection is
+ * set to that collection, name is null, isRoot equals false;
+ * <li>Path matches some document's canonical name - collection is set
+ * to the document's collection, name is document name, isRoot equals
+ * false;
+ * <li>Path could not be recognized, no database/collection match found -
+ * both collection and name are null, isRoot equals false
+ * </ul>
+ * In case there are collection and document that have the same name,
+ * collection has a precedence over the document.
+ * For example, if path is /db/col1/test, and collection col1 contains
+ * child collection test and a document test, collection test will be
+ * returned, not a document.
+ *
+ * @param path Path string
+ * @throws DBException
+ */
+ public Location(String path) throws DBException {
+ if (path == null || path.length() == 0 || path.equals("/")) {
+ isRoot = true;
+ return;
+ }
+
+ Database db = getDatabase(path);
+ if (db == null) {
+ collection = null;
+ name = null;
+ return;
+ }
+
+ StringBuffer buf = new StringBuffer(path);
+
+ // strip database name
+ String dbName = db.getName();
+ buf.delete(0, dbName.length() + 1);
+
+ Collection col;
+ if (buf.length() == 0 || (buf.length() == 1 && buf.charAt(0) == '/')) {
+ col = db;
+ } else {
+ col = db.getCollection(buf.toString());
+ }
+
+ String resourceName = null;
+ if (col == null) { // no collection found -> try resource
+ if (buf.charAt(buf.length() - 1) == '/') {
+ buf.deleteCharAt(buf.length() - 1);
+ }
+
+ int split = buf.lastIndexOf("/");
+ resourceName = buf.substring(split + 1, buf.length());
+ String colPath = buf.substring(0, split);
+
+ if (colPath.length() > 0) {
+ col = db.getCollection(colPath);
+ } else {
+ col = db;
+ }
+ }
+
+ collection = col;
+ if (collection != null) {
+ this.name = resourceName;
+ }
+ }
+
+ private Database getDatabase(String path) {
+ if (path.charAt(0) != '/') {
+ return null;
+ }
+
+ int end = path.indexOf('/', 1);
+ String dbName = (end != -1) ? path.substring(1, end) : path.substring(1);
+
+ return Database.getDatabase(dbName);
+ }
+
+ public Collection getCollection() {
+ return collection;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isRoot() {
+ return isRoot;
+ }
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/Location.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/Location.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/PartialResponse.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/PartialResponse.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/PartialResponse.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/PartialResponse.java Thu May 24 18:43:39 2007
@@ -0,0 +1,150 @@
+/*
+ * 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.xindice.webadmin;
+
+import org.apache.xindice.util.StringUtilities;
+
+import java.util.ArrayList;
+
+/**
+ * PartialResponse represents response part of the multi-status response
+ * document. Every partial response has its correspondent URL information
+ * (href element) and one or more elements with additional request-specific
+ * information.
+ */
+public class PartialResponse {
+ private final String href;
+ private ArrayList children;
+
+ public PartialResponse(String href) {
+ this.href = href;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * Adds another element to the list of children of this partial response.
+ *
+ * @param name Element name
+ * @param value Element value
+ */
+ public void addContent(String name, String value) {
+ Content child = new Content(name);
+ child.setValue(value);
+ addContent(child);
+ }
+
+ /**
+ * Adds another element to the list of children of this partial response.
+ *
+ * @param child Existing element
+ */
+ public void addContent(Content child) {
+ if (children == null) {
+ children = new ArrayList();
+ }
+ children.add(child);
+ }
+
+ /**
+ * Builds XML out of partial response object.
+ *
+ * @return XML string
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer(1024);
+ buf.append("<response>");
+ buf.append("<href>").append(StringUtilities.escapeXml(href)).append("</href>");
+
+ if (children != null && children.size() != 0) {
+ for (int i = 0; i < children.size(); i++) {
+ buf.append(((Content) children.get(i)).getContent());
+ }
+ }
+
+ buf.append("</response>");
+
+ return buf.toString();
+ }
+
+ /**
+ * Content class holds request-specific information in a tree-like
+ * structure. Every element of this tree can either be empty, have a
+ * text value or hold children elements.
+ */
+ public static class Content {
+ private ArrayList children;
+ private String name;
+ private String value;
+
+ public Content(String name) {
+ this.name = name;
+ }
+
+ public Content(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public Content addChild(String name) {
+ Content child = new Content(name);
+ addChild(child);
+ return child;
+ }
+
+ public Content addChild(String name, String value) {
+ Content child = addChild(name);
+ child.setValue(value);
+ return child;
+ }
+
+ public void addChild(Content child) {
+ if (children == null) {
+ children = new ArrayList();
+ }
+ children.add(child);
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ private StringBuffer getContent() {
+ StringBuffer buf = new StringBuffer(1024);
+
+ buf.append("<").append(name).append(">");
+ if (value != null) {
+ buf.append(StringUtilities.escapeXml(value));
+ } else if (children != null && children.size() != 0) {
+ for (int i = 0; i < children.size(); i++) {
+ buf.append(((Content) children.get(i)).getContent());
+ }
+ }
+
+ buf.append("</").append(name).append(">");
+
+ return buf;
+ }
+ }
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/PartialResponse.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/PartialResponse.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminManager.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminManager.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminManager.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminManager.java Thu May 24 18:43:39 2007
@@ -0,0 +1,206 @@
+/*
+ * 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.xindice.webadmin;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.apache.xindice.webadmin.webdav.components.DAVComponent;
+import org.apache.xindice.webadmin.viewer.HtmlCollectionViewer;
+import org.apache.xindice.webadmin.viewer.HtmlResourceViewer;
+import org.apache.xindice.webadmin.viewer.HtmlDatabaseViewer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.HashMap;
+import java.util.ArrayList;
+
+/**
+ * Manager class that is responsible for reading configuration, initializing
+ * all components, and dispatching calls.
+ *
+ * WebAdminManager configuration has several sections descibing different
+ * components:
+ * <ul>
+ * <li>methods - list of supported WebDAV methods
+ * <li>colviewers - list of collection-level operations for WebAdmin
+ * <li>resviewers - list of resource-level operations for WebAdmin
+ * <li>dbviewers - list of database-level operations for WebAdmin
+ * </ul>
+ */
+public class WebAdminManager {
+
+ private static final HashMap methods = new HashMap();
+ private static final HashMap colViewers = new HashMap();
+ private static final HashMap resViewers = new HashMap();
+ private static final HashMap dbViewers = new HashMap();
+
+ private static String[] methodsList;
+ private static String[] colViewersList;
+ private static String[] resViewersList;
+ private static String[] dbViewersList;
+
+ private static final Log log = LogFactory.getLog(WebAdminManager.class);
+
+ public WebAdminManager(Document config) {
+ Node node = config.getElementsByTagName("methods").item(0);
+ try {
+ methodsList = processSection(node, "method", methods);
+ } catch (Exception e) {
+ log.error("Failed to load WebDAV methods", e);
+ }
+
+ node = config.getElementsByTagName("colviewers").item(0);
+ try {
+ colViewersList = processSection(node, "viewer", colViewers);
+ } catch (Exception e) {
+ log.error("Failed to load collection viewers", e);
+ }
+
+ node = config.getElementsByTagName("resviewers").item(0);
+ try {
+ resViewersList = processSection(node, "viewer", resViewers);
+ } catch (Exception e) {
+ log.error("Failed to load resource viewers", e);
+ }
+
+ node = config.getElementsByTagName("dbviewers").item(0);
+ try {
+ dbViewersList = processSection(node, "viewer", dbViewers);
+ } catch (Exception e) {
+ log.error("Failed to load DB viewers", e);
+ }
+ }
+
+ private String[] processSection(Node node, String name, HashMap storage) throws Exception {
+ NodeList nodes = node.getChildNodes();
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < nodes.getLength(); i++) {
+
+ Node child = nodes.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(name)) {
+ NamedNodeMap attrs = child.getAttributes();
+
+ String className = attrs.getNamedItem("class").getNodeValue();
+ Object object = Class.forName(className).newInstance();
+
+ String id = attrs.getNamedItem("id").getNodeValue();
+ if (id != null && id.length() > 0) {
+ storage.put(id, object);
+ list.add(id);
+
+ Node attr = attrs.getNamedItem("default");
+ if (attr != null && "true".equals(attr.getNodeValue())) {
+ storage.put("default", object);
+ }
+ }
+ }
+ }
+
+ return (String[]) list.toArray(new String[0]);
+ }
+
+ /**
+ * Gets class that handles specific DAV request.
+ *
+ * @param id Method name (e.g. PROPFIND, MKCOL)
+ * @return applicable class, if it has been configured, null otherwise
+ */
+ public DAVComponent getMethod(String id) {
+ return (DAVComponent) methods.get(id);
+ }
+
+ /**
+ * Gets class that handles specific collection-level operation for WebAdmin.
+ *
+ * @param id Opration id
+ * @return applicable class, if it has been configured, null otherwise
+ */
+ public HtmlCollectionViewer getCollectionViewer(String id) {
+ if (id == null || id.length() == 0) {
+ id = "default";
+ }
+
+ return (HtmlCollectionViewer) colViewers.get(id);
+ }
+
+ /**
+ * Gets class that handles specific resource-level operation for WebAdmin.
+ *
+ * @param id Opration id
+ * @return applicable class, if it has been configured, null otherwise
+ */
+ public HtmlResourceViewer getResourceViewer(String id) {
+ if (id == null || id.length() == 0) {
+ id = "default";
+ }
+
+ return (HtmlResourceViewer) resViewers.get(id);
+ }
+
+ /**
+ * Gets class that handles specific database-level operation for WebAdmin.
+ *
+ * @param id Opration id
+ * @return applicable class, if it has been configured, null otherwise
+ */
+ public HtmlDatabaseViewer getDatabaseViewer(String id) {
+ if (id == null || id.length() == 0) {
+ id = "default";
+ }
+
+ return (HtmlDatabaseViewer) dbViewers.get(id);
+ }
+
+ /**
+ * Gets all supported methods.
+ *
+ * @return Array of all supported WebDAV methods.
+ */
+ public static String[] getMethods() {
+ return methodsList;
+ }
+
+ /**
+ * Gets all supported database-level operations.
+ *
+ * @return Array of all supported database-level operations.
+ */
+ public static String[] getDatabaseViewers() {
+ return dbViewersList;
+ }
+
+ /**
+ * Gets all supported collection-level operations.
+ *
+ * @return Array of all supported collection-level operations.
+ */
+ public static String[] getCollectionViewers() {
+ return colViewersList;
+ }
+
+ /**
+ * Gets all supported resource-level operations.
+ *
+ * @return Array of all supported resource-level operations.
+ */
+ public static String[] getResourceViewers() {
+ return resViewersList;
+ }
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminManager.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminServlet.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminServlet.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminServlet.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminServlet.java Thu May 24 18:43:39 2007
@@ -19,21 +19,28 @@
package org.apache.xindice.webadmin;
-import java.io.File;
import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.InputStream;
import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.ContainerManager;
-import org.apache.avalon.fortress.impl.DefaultContainerManager;
-import org.apache.avalon.fortress.util.FortressConfig;
-import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.xindice.server.XindiceServlet;
-import org.apache.xindice.core.Database;
+import org.apache.xindice.xml.dom.DOMParser;
+import org.apache.xindice.core.DBException;
+import org.apache.xindice.core.Collection;
+import org.apache.xindice.webadmin.webdav.components.DAVComponent;
+import org.apache.xindice.webadmin.webdav.WebdavStatus;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.util.MimeTable;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
/**
* @author <a href="mailto:jan@metzner.org">Jan Metzner</a>
@@ -41,71 +48,144 @@
*/
public class WebAdminServlet extends XindiceServlet {
- protected WebAdminContainer m_container;
- protected ContainerManager m_containerManager;
+ protected WebAdminManager mgr;
- /**
- * Initializes Servlet and creates a WebAdminContainer instance
- *
- * @exception ServletException if an error occurs
- */
- public void init(ServletConfig servletConfig) throws ServletException {
- super.init(servletConfig);
- try {
-
- ServletContext servletContext = servletConfig.getServletContext();
-
- final FortressConfig config = new FortressConfig();
- config.setContainerClass(WebAdminContainer.class);
- config.setContextDirectory( servletContext.getRealPath("/") );
- config.setWorkDirectory( (File) servletContext
- .getAttribute( "javax.servlet.context.tempdir" ) );
- config.setContainerConfiguration(
- "resource://org/apache/xindice/webadmin/WebAdmin.xconf");
- config.setLoggerManagerConfiguration(
- "resource://org/apache/xindice/webadmin/WebAdmin.xlog");
-
- m_containerManager = new DefaultContainerManager( config.getContext() );
- ContainerUtil.initialize(m_containerManager);
-
- m_container = (WebAdminContainer)m_containerManager.getContainer();
- } catch(Exception e) {
- throw new ServletException( "Error during initialization", e );
- }
- }
-
- /**
- * Pass all servlet requests through to container to be handled.
- *
- * @param req a HttpServletRequest instance
- * @param res a HttpServletResponse instance
- * @exception IOException if an IO error occurs
- * @exception ServletException if a servlet error occurs
- */
- public void service(HttpServletRequest req, HttpServletResponse res)
- throws IOException, ServletException {
-
- // get request path
- String path = req.getPathInfo();
- if(path == null) {
- path = "";
- }
-
- // xmlrpc request are handled by the XindiceServlet
- if(req.getMethod().equalsIgnoreCase("POST") && path.length() < 2) {
- super.doPost(req, res);
- } else {
- // HACK Get first database and use it. Should be changed to support multiple databases
- String[] databases = Database.listDatabases();
- m_container.handleRequest(req, res, Database.getDatabase(databases[0]));
- }
- }
-
- /**
- * Disposes of container manager and container instance.
- */
- public void destroy() {
- super.destroy();
- ContainerUtil.dispose(m_containerManager);
- }
+ private static final Log log = LogFactory.getLog(WebAdminServlet.class);
+ private static final String WEBADMIN_CONFIGURATION = "webadmin.configuration";
+ private static final String MIMETABLE_CONFIGURATION = "mimetable.configuration";
+
+ /**
+ * Initializes Servlet and creates a WebAdminContainer instance
+ *
+ * @exception ServletException if an error occurs
+ */
+ public void init(ServletConfig servletConfig) throws ServletException {
+
+ super.init(servletConfig);
+ try {
+ String path = servletConfig.getInitParameter(WEBADMIN_CONFIGURATION);
+ Document configuration = loadFile(path, servletConfig);
+ mgr = new WebAdminManager(configuration);
+ } catch(Exception e) {
+ throw new ServletException("Could not process WebAdmin configuration", e);
+ }
+
+ try {
+ String path = servletConfig.getInitParameter(MIMETABLE_CONFIGURATION);
+ Document configuration = loadFile(path, servletConfig);
+ MimeTable.addMimeConfig(configuration);
+
+ } catch(Exception e) {
+ log.error("Could not process Mime Table configuration", e);
+ }
+ }
+
+ private Document loadFile(String path, ServletConfig config) throws Exception {
+ InputStream inputStream = null;
+
+ try {
+ if (path.startsWith("/")) { // Absolute file path
+ log.debug("Loading configuration from filesystem path " + path);
+ inputStream = new FileInputStream(path);
+ } else {
+ // Relative (to the context) path
+ log.debug("Loading configuration from context path " + path);
+ ServletContext context = config.getServletContext();
+ inputStream = context.getResourceAsStream("/" + path);
+ }
+
+ Document configuration = null;
+ if (inputStream != null) {
+ configuration = DOMParser.toDocument(inputStream);
+ }
+
+ return configuration;
+ } finally {
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (IOException ignored) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Pass all servlet requests through to container to be handled.
+ *
+ * @param req a HttpServletRequest instance
+ * @param res a HttpServletResponse instance
+ * @exception IOException if an IO error occurs
+ * @exception ServletException if a servlet error occurs
+ */
+ public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
+
+ // get request path
+ String path = req.getPathInfo();
+
+ // xmlrpc request are handled by the XindiceServlet
+ if(req.getMethod().equalsIgnoreCase("POST") && (path == null || path.length() < 2)) {
+ super.doPost(req, res);
+ } else {
+ process(req, res);
+ }
+ }
+
+ private void process(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
+
+ // get request path
+ String path = req.getPathInfo();
+
+ // get content
+ Location target;
+ try {
+ target = new Location(path);
+ } catch (DBException e) {
+ log.error(e);
+ throw new ServletException(e);
+ }
+
+ Collection col = target.getCollection();
+ String resource = target.getName();
+
+ // choose html interface
+ String viewer = req.getParameter("viewer");
+
+ if (viewer == null || viewer.length() == 0) { // not html request
+ DAVComponent method = mgr.getMethod(req.getMethod());
+
+ if (method == null) {
+ // method is not supported
+ if (log.isWarnEnabled()) {
+ log.warn("Method " + req.getMethod() + " is not supported.");
+ }
+ res.setStatus(WebdavStatus.SC_NOT_IMPLEMENTED);
+ return;
+ }
+
+ DAVRequest request = new DAVRequest(req);
+ DAVResponse response = new DAVResponse(res);
+ method.execute(request, response, target);
+ } else { // html request
+ if (col == null) {
+ if (!"/".equals(path)) {
+ String redirect = req.getContextPath() + req.getServletPath() + "/?viewer=" + viewer;
+ res.sendRedirect(redirect);
+ }
+
+ mgr.getDatabaseViewer(viewer).execute(req, res);
+ } else if (resource == null) {
+ // redirect if path does not end with /
+ if (!path.endsWith("/")) {
+ String redirect = req.getContextPath() + req.getServletPath() + path + "/?viewer=" + viewer;
+ res.sendRedirect(redirect);
+ }
+
+ mgr.getCollectionViewer(viewer).execute(req, res, col);
+ } else {
+ mgr.getResourceViewer(viewer).execute(req, res, col, resource);
+ }
+ }
+ }
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/WebAdminServlet.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/CollectionConfigurationHelper.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/CollectionConfigurationHelper.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/CollectionConfigurationHelper.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/CollectionConfigurationHelper.java Thu May 24 18:43:39 2007
@@ -14,69 +14,155 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * $Id$
- */
+ * CVS $Id$
+ */
package org.apache.xindice.webadmin.util;
import org.apache.xindice.core.Collection;
import org.apache.xindice.util.Configuration;
-import org.apache.xindice.util.XindiceException;
+import org.apache.xindice.util.ReadOnlyException;
+import org.apache.xindice.xml.TextWriter;
+import org.apache.xindice.xml.dom.DocumentImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
/**
- *
+ * Helper class for oprations on collection configuration
+ *
* @author <a href="mailto:jmetzner@apache.org">Jan Metzner</a>
* @version $Id$
*/
-public interface CollectionConfigurationHelper {
-
- /** Role identifying Component */
- String ROLE = CollectionConfigurationHelper.class.getName();
+public class CollectionConfigurationHelper {
+ private static final Log log = LogFactory.getLog(CollectionConfigurationHelper.class);
public static final String CONF_ELE = "collection";
-
- public static final String COL_NAME_ATTR = "name";
-
+ public static final String COL_NAME_ATTR = "name";
public static final String INLINE_META_ATTR = "inline-metadata";
-
public static final String COMPRESSED_ATTR = "compressed";
-
public static final String FILER_ELE = "filer";
-
public static final String FILER_CLASS_ATTR = "class";
-
public static final boolean DEFAULT_INLINE_META = true;
-
public static final boolean DEFAULT_COMPRESSED = true;
+ public static final String DEFAULT_FILER_CLASS = "org.apache.xindice.core.filer.BTreeFiler";
- public static final String DEFAULT_FILER_CLASS =
- "org.apache.xindice.core.filer.BTreeFiler";
-
- public boolean isAutoEnableInlineMeta();
-
- public boolean getDefaultInlineMetadata();
-
- public boolean getDefaultCompressed();
-
- public String getDefaultFilerClass();
-
- public boolean isInlineMetaEnabled(final Collection col);
-
- public Configuration createDefaultConfiguration(String name);
-
- public Configuration createConfiguration(
- String name,
- String compressed,
- String inlineMeta,
- String filerClass);
-
- public void enableCollectionInlineMetadata(Collection col)
- throws XindiceException;
-
- public Configuration copyConfiguration(final Configuration srcConfig);
-
- public Configuration copyConfiguration(
- String name,
- final Configuration srcConfig);
-}
\ No newline at end of file
+ /**
+ * Configures the CollectionConfigurationHelper with the default
+ * Collection Configuration. Example:
+ * <pre>
+ * <col-config id="col-config" autoenableinlinemeta="true">
+ * <collection compressed="true" inline-meta="true">
+ * <filer class="org.apache.xindice.core.filer.BTreeFiler" />
+ * </collection>
+ * </col-config>
+ * </pre>
+ * A name Attribute will be ignored.
+ * If the Attribute autoenableinlinemeta is set true, the Collection is not Inline
+ * Metadata enabled and a Binary is inserted, the Collection will be automatically
+ * Inline Metadata enabled.
+ */
+ public static boolean getDefaultInlineMetadata() {
+ return DEFAULT_INLINE_META;
+ }
+
+ public static boolean getDefaultCompressed() {
+ return DEFAULT_COMPRESSED;
+ }
+
+ public static String getDefaultFilerClass() {
+ return DEFAULT_FILER_CLASS;
+ }
+
+ public static boolean isInlineMetaEnabled(final Collection col) {
+ Configuration config = col.getConfig();
+ return config.getBooleanAttribute(INLINE_META_ATTR, false);
+ }
+
+ public static Configuration createDefaultConfiguration(String name) {
+ return createConfiguration(name, null, null, null);
+ }
+
+ public static Configuration createConfiguration(String name, String compressed, String inlineMeta, String filerClass) {
+ Document doc = new DocumentImpl();
+ Element colEle = doc.createElement(CONF_ELE);
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("null name");
+ }
+ colEle.setAttribute(COL_NAME_ATTR, name);
+ if (compressed == null || (!compressed.equalsIgnoreCase("true") && !compressed.equalsIgnoreCase("false"))) {
+ compressed = Boolean.toString(DEFAULT_COMPRESSED);
+ }
+ colEle.setAttribute(COMPRESSED_ATTR, compressed);
+ if (inlineMeta == null || (!inlineMeta.equalsIgnoreCase("true") && !inlineMeta.equalsIgnoreCase("false"))) {
+ inlineMeta = Boolean.toString(DEFAULT_INLINE_META);
+ }
+ colEle.setAttribute(INLINE_META_ATTR, inlineMeta);
+ doc.appendChild(colEle);
+ Element filEle = doc.createElement(FILER_ELE);
+ if (filerClass == null || filerClass.length() == 0) {
+ filerClass = DEFAULT_FILER_CLASS;
+ }
+ filEle.setAttribute(FILER_CLASS_ATTR, filerClass);
+ colEle.appendChild(filEle);
+ if (log.isDebugEnabled()) {
+ log.debug("Created Configuration: \n" + TextWriter.toString(doc));
+ }
+ return new Configuration(doc.getDocumentElement(), false);
+ }
+
+ public static Configuration copyConfiguration(final Configuration srcConfig) {
+ Configuration newConfig = createConfiguration();
+ try {
+ return copyConfigurationContent(srcConfig, newConfig);
+ } catch (ReadOnlyException e) {
+ log.error(e);
+ return null;
+ }
+ }
+
+ public static Configuration copyConfiguration(String name, final Configuration srcConfig) {
+ Configuration destConfig = createConfiguration();
+ try {
+ copyConfigurationContent(srcConfig, destConfig);
+ destConfig.setAttribute(COL_NAME_ATTR, name);
+ } catch (ReadOnlyException e) {
+ // ignore, cannot happen
+ }
+
+ return destConfig;
+ }
+
+ private static Configuration copyConfigurationContent(final Configuration srcConfig, Configuration destConfig)
+ throws ReadOnlyException {
+
+ if (srcConfig.hasAttributes()) {
+ String[] attrs = srcConfig.listAttributes();
+ for (int i = 0; i < attrs.length; i++) {
+ destConfig.setAttribute(attrs[i], srcConfig.getAttribute(attrs[i]));
+ }
+ }
+ if (srcConfig.hasValue()) {
+ String value = srcConfig.getValue(null);
+ if (value != null) {
+ destConfig.setValue(value);
+ }
+ }
+ if (srcConfig.hasChildren()) {
+ Configuration[] childConf = srcConfig.getChildren();
+ for (int i = 0; i < childConf.length; i++) {
+ Configuration childDestConfig = destConfig.getChild(childConf[i].getName(), true);
+ copyConfigurationContent(childConf[i], childDestConfig);
+ }
+ }
+
+ return destConfig;
+ }
+
+ private static Configuration createConfiguration() {
+ Document doc = new DocumentImpl();
+ return new Configuration(doc.createElement(CONF_ELE), false);
+ }
+}
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/DAVOperations.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/DAVOperations.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/DAVOperations.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/DAVOperations.java Thu May 24 18:43:39 2007
@@ -19,80 +19,232 @@
package org.apache.xindice.webadmin.util;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.avalon.framework.service.ServiceException;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
+import org.apache.xindice.core.FaultCodes;
+import org.apache.xindice.core.data.Key;
+import org.apache.xindice.core.data.Entry;
+import org.apache.xindice.webadmin.webdav.WebdavStatus;
+import org.apache.xindice.webadmin.Location;
+import org.apache.xindice.util.Configuration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Collections;
-/**
- * Some usefull Operations like Copy or Move.
- *
+/**
+ * Helper for copy/move operations.
+ *
* @author <a href="mailto:jmetzner@apache.org">Jan Metzner</a>
- * @version $Id$
+ * @version $Id$
*/
-public interface DAVOperations {
- /** Role identifying Component */
- String ROLE = DAVOperations.class.getName();
-
- /**
- * Copies the collection or resource spcified by parentCol and name
- * to the destination specified by the destination header of the request.
- *
- * @param req servlet request.
- * @param parentCol parent collection.
- * @param name name of the source resource/collection
- * @return WEBDAV Status Code.
- * @throws DBException while writing the new resource/collection.
- */
- public abstract int copy(
- HttpServletRequest req,
- Collection parentCol,
- String name)
- throws DBException, ServiceException;
-
- /**
- * gets the destination path header from Copy and Move requests.
- *
- * @param req servlet request.
- * @return destination path or null if the header does not exits.
- */
- public abstract String getDestinationPath(HttpServletRequest req);
-
- /**
- * Parses the overwrite header of the given request.
- *
- * @param req servlet request.
- * @return the boolean value of the overwrite header
- * (true if the header does not exist).
- */
- public abstract boolean getOverwrite(HttpServletRequest req);
-
+public class DAVOperations {
+
+ private static final Log log = LogFactory.getLog(DAVOperations.class);
+
/**
- * copies the entire collection to a new destination.
- *
- * @param srcCol source collection.
- * @param destParentCol parent collection of the destination.
- * @param name name of the new collection.
- * @throws DBException while creating the new collection.
- * @return the new created collection.
+ * Copies collection to the new destination
+ * @param col Collection to be copied
+ * @param dest Destination path (includes DB name)
+ * @param overwrite true if previously existed collection at dest path can be overwritten
+ * @return
+ * @throws DBException
*/
- public abstract Collection copyCollection(
- Collection srcCol,
- Collection destParentCol,
- String name)
- throws DBException, ServiceException;
-
+ public static Map copy(Collection col, String dest, boolean overwrite, boolean deep) throws DBException {
+
+ Location destLocation = new Location(dest);
+ Collection destCollection = destLocation.getCollection();
+ String destName = destLocation.getName();
+ Map results = new HashMap();
+
+ if (destLocation.isRoot()) {
+ results.put(dest, new Integer(WebdavStatus.SC_BAD_REQUEST));
+ return results;
+ } else if (destCollection == null) {
+ // either intermidiate collection does not exist or destination points to
+ // the first level collection (database).
+ results.put(dest, new Integer(WebdavStatus.SC_CONFLICT));
+ return results;
+ } else if (deep && destCollection.getCanonicalName().startsWith(col.getCanonicalName())) {
+ // destination points to a location inside target collection subtree.
+ // deep copy does not make sense in that case
+ results.put(dest, new Integer(WebdavStatus.SC_FORBIDDEN));
+ return results;
+ }
+
+ // FIXME: the operations are not atomic, they can fail because of another
+ // thread deleting or creating collections. Introduce locks.
+ if (destName != null) { // destination collection does not exist
+
+ results.putAll(copyCollection(col, destCollection, destName, deep));
+ if (results.size() == 0) {
+ results.put(dest, new Integer(WebdavStatus.SC_CREATED));
+ }
+ } else { // existing collection
+
+ if (overwrite) {
+ // overwrites the collection
+ String name = destCollection.getName();
+ Collection parent = destCollection.getParentCollection();
+ // delete collection
+ parent.dropCollection(destCollection);
+ results.putAll(copyCollection(col, parent, name, deep));
+ if (results.size() == 0) {
+ results.put(dest, new Integer(WebdavStatus.SC_NO_CONTENT));
+ }
+ } else {
+ results.put(dest, new Integer(WebdavStatus.SC_PRECONDITION_FAILED));
+ }
+
+ }
+
+ return results;
+ }
+
/**
- * copies the collection content (resources and collections).
- *
- * @param srcCol source collection.
- * @param destCol destination collection.
- * @throws DBException while creating the new content.
+ * Copies a resource to a new location.
+ * @param col Source collection
+ * @param name Resource name
+ * @param dest Path to the new location. It includes db name and new resource name
+ * @param overwrite true if previously existed resource at dest path can be overwritten
+ * @return
+ * @throws DBException
*/
- public abstract void copyCollectionContent(
- Collection srcCol,
- Collection destCol)
- throws DBException, ServiceException;
-}
\ No newline at end of file
+ public static int copy(Collection col, String name, String dest, boolean overwrite) throws DBException {
+
+ Location destLocation = new Location(dest);
+ Collection destCollection = destLocation.getCollection();
+ String destName = destLocation.getName();
+
+ if (destLocation.isRoot()) {
+ // resource cannot be added to root directly, database has to be created manually
+ return WebdavStatus.SC_FORBIDDEN;
+ } else if (destCollection == null) {
+ return WebdavStatus.SC_CONFLICT;
+ } else if (col == destCollection && name.equals(destName)) {
+ return WebdavStatus.SC_FORBIDDEN;
+ }
+
+ // get source
+ Entry object = col.getEntry(name);
+ if (object == null) {
+ return WebdavStatus.SC_NOT_FOUND;
+ }
+
+ int status;
+ try {
+ if (object.getEntryType() == Entry.BINARY) { // insert Binary
+ if (overwrite) {
+ if (destCollection.setBinary(new Key(destName), (byte[]) object.getValue())) {
+ status = WebdavStatus.SC_CREATED;
+ } else {
+ status = WebdavStatus.SC_NO_CONTENT;
+ }
+ } else {
+ destCollection.insertBinary(destName, (byte[]) object.getValue());
+ status = WebdavStatus.SC_CREATED;
+ }
+ } else if (object.getEntryType() == Entry.DOCUMENT) {
+ if (overwrite) {
+ if (destCollection.setDocument(new Key(destName), (Document) object.getValue())) {
+ status = WebdavStatus.SC_CREATED;
+ } else {
+ status = WebdavStatus.SC_NO_CONTENT;
+ }
+ } else {
+ destCollection.insertDocument(destName, (Document) object.getValue());
+ status = WebdavStatus.SC_CREATED;
+ }
+ } else {
+ // placeholder, won't get here
+ status = WebdavStatus.SC_FORBIDDEN;
+ }
+ } catch (DBException e) {
+ if (e.faultCode == FaultCodes.COL_DUPLICATE_RESOURCE) {
+ status = WebdavStatus.SC_PRECONDITION_FAILED;
+ } else if (e.faultCode == FaultCodes.COL_NO_FILER) {
+ status = WebdavStatus.SC_FORBIDDEN;
+ } else if (e.faultCode == FaultCodes.COL_COLLECTION_NOT_FOUND) {
+ status = WebdavStatus.SC_CONFLICT;
+ } else if (e.faultCode == FaultCodes.COL_CANNOT_STORE) {
+ if (log.isDebugEnabled()) {
+ log.debug("Collection Inline Metadata is not enabled!");
+ }
+ status = WebdavStatus.SC_FORBIDDEN;
+ } else {
+ throw e;
+ }
+ }
+
+ return status;
+ }
+
+ private static Map copyCollection(Collection col, Collection parent, String name, boolean deep)
+ throws DBException {
+
+ Configuration config = CollectionConfigurationHelper.copyConfiguration(name, col.getConfig());
+ Collection newCol = parent.createCollection(name, config);
+
+ if (deep) {
+ return copyCollectionContent(col, newCol);
+ } else {
+ return Collections.EMPTY_MAP;
+ }
+ }
+
+ private static Map copyCollectionContent(Collection srcCol, Collection destCol) throws DBException {
+ HashMap result = new HashMap();
+
+ // copy resources
+ String[] resList = srcCol.listDocuments();
+ for (int i = 0; i < resList.length; i++) {
+ Entry object = srcCol.getEntry(resList[i]);
+ if (object.getEntryType() == Entry.DOCUMENT) {
+ destCol.setDocument(resList[i], (Document) object.getValue());
+ } else {
+ destCol.setBinary(resList[i], (byte[]) object.getValue());
+ }
+ }
+
+ // copy child collections content collections
+ /* From the specification:
+ If an error occurs while copying an internal collection, the server MUST NOT
+ copy any resources identified by members of this collection (i.e., the server
+ must skip this subtree), as this would create an inconsistent namespace.
+ After detecting an error, the COPY operation SHOULD try to finish as much
+ of the original copy operation as possible (i.e., the server should still
+ attempt to copy other subtrees and their members, that are not descendents
+ of an error-causing collection).
+ */
+ String[] colList = srcCol.listCollections();
+ for (int i = 0; i < colList.length; i++) {
+ Collection srcChild = srcCol.getCollection(colList[i]);
+ Collection destChild = destCol.getCollection(colList[i]);
+ try {
+ result.putAll(copyCollectionContent(srcChild, destChild));
+ } catch (DBException e) {
+ int code;
+ if (e.faultCode == FaultCodes.COL_NO_FILER) {
+ code = WebdavStatus.SC_FORBIDDEN;
+ } else if (e.faultCode == FaultCodes.COL_COLLECTION_NOT_FOUND) {
+ code = WebdavStatus.SC_CONFLICT;
+ } else if (e.faultCode == FaultCodes.COL_CANNOT_STORE) {
+ if (log.isDebugEnabled()) {
+ log.debug("Collection Inline Metadata is not enabled!");
+ }
+ code = WebdavStatus.SC_FORBIDDEN;
+ } else {
+ throw e;
+ }
+
+ result.put(destChild.getCanonicalName(), new Integer(code));
+ }
+ }
+
+ return result;
+ }
+}
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/MimeTable.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/MimeTable.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/MimeTable.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/util/MimeTable.java Thu May 24 18:43:39 2007
@@ -14,54 +14,192 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * $Id$
+ * CVS $Id$
*/
package org.apache.xindice.webadmin.util;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.apache.xindice.xml.dom.DOMParser;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
/**
- * MimeTable maps a file extension to a mime type.
+ * MimeTable maps a file extension to a mime type.
*
* @author <a href="mailto:jmetzner@apache.org">Jan Metzner</a>
* @version $Id$
*/
-public interface MimeTable {
-
- /** Role identifying Component */
- String ROLE = MimeTable.class.getName();
-
- /** the default mime type for binaries */
- public static final String BINARY_MIME_TYPE = "application/octet-stream";
-
- /** the default mime type for xml documents */
- public static final String XML_MIME_TYPE = "text/xml";
-
- /**
- * returns the mime type of the given object.
- *
- * @param resource the object.
- * @param name the name of the object.
- * @return mime type for this object.
- */
- public abstract String getMimeType(Object resource, String name);
-
- /**
- * returns the mime type for the given name.
- * if no mime for this name is available the default xml mime type is returned.
- *
- * @param recourceName the name of the resource.
- * @return mime type for this resource name.
- */
- public abstract String getMimeType(String recourceName);
-
- /**
- * returns the mime type for the given name.
- * if no mime for this name is available the parameter defaultXml specifies if
- * the xml mime type or the binary mime type are returned.
- *
- * @param resourceName
- * @param defaultXml
- * @return
- */
- public abstract String getMimeType(String resourceName, boolean defaultXml);
-}
\ No newline at end of file
+public class MimeTable {
+
+ /** the default mime type for binaries */
+ public static final String BINARY_MIME_TYPE = "application/octet-stream";
+
+ /** the default mime type for xml documents */
+ public static final String XML_MIME_TYPE = "text/xml";
+
+ /** holds the extensions/mime types */
+ protected static Hashtable mimeMappings = new Hashtable();
+
+ private final static Log log = LogFactory.getLog(MimeTable.class);
+
+ /**
+ * Configures the Mime table.
+ * the configuration can look like the Configuration in the
+ * addMimeConfig(Configuration config) Method<br />
+ * <br/>
+ * or if the Configuration should be loaded out of an extra file:
+ * <pre>
+ * <mime location="/some/path">
+ * </pre>
+ * or if the Configuration should be loaded out of the Classpath:
+ * <pre>
+ * <mime location="resource://org.a.MyFile">
+ * </pre>
+ */
+ public static void configure(String location) {
+ // load mime table
+ boolean loadFromClasspath = false;
+ if (location.startsWith("resource://")) {
+ loadFromClasspath = true;
+ location = location.substring(11);
+ }
+
+ try {
+ if (loadFromClasspath) {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResource(location).openStream();
+ if (log.isDebugEnabled()) {
+ log.debug("Load Configuration from Classpath: " + location);
+ }
+ addMimeConfig(DOMParser.toDocument(is));
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Load Configuration from File: " + location);
+ }
+ addMimeConfig(DOMParser.toDocument(location));
+ }
+ } catch (Exception e) {
+ log.error("Could not load MimeTable configuration", e);
+ }
+ }
+
+ /**
+ * Add the given mime Document to this mime table.
+ * the mime Document looks like this:
+ * <pre>
+ * <mime>
+ * <mime-mapping>
+ * <extension>xml</extension>
+ * <mime-type>xml</mime-type>
+ * </mime-mapping>
+ * ...
+ * </mime>
+ * </pre>
+ *
+ * @param doc mime config.
+ */
+ public static void addMimeConfig(Document doc) {
+ NodeList mapping = doc.getChildNodes();
+ for (int i = 0; i < mapping.getLength(); i++) {
+ NodeList thisMapping = mapping.item(i).getChildNodes();
+ String ext = "";
+ String type = "";
+ for (int j = 0; j < thisMapping.getLength(); j++) {
+ if (thisMapping.item(j).getNodeName().equalsIgnoreCase("extension")) {
+ ext = thisMapping.item(j).getNodeValue();
+ } else if (thisMapping.item(j).getNodeName().equalsIgnoreCase("mime-type")) {
+ type = thisMapping.item(j).getNodeValue();
+ }
+ }
+ mimeMappings.put(ext, type);
+ }
+ }
+
+ /**
+ * Returns the mime type for the given name.
+ * If no mime for this name is available the parameter defaultXml specifies if
+ * the xml mime type or the binary mime type are returned.
+ *
+ * @param resourceName
+ * @return mime type for this resource name
+ */
+ public static String getMimeType(String resourceName) {
+ int split = resourceName.lastIndexOf('.');
+ String mime = null;
+ if (split > 0) {
+ mime = (String) mimeMappings.get(resourceName.substring(split + 1));
+ }
+
+ if (mime != null) {
+ return mime;
+ } else {
+ return BINARY_MIME_TYPE;
+ }
+ }
+
+ private static void writeMappingAsXml(HashMap mappings, Writer out) throws IOException {
+ out.write("<?xml version=\"1.0\"?>\n");
+ out.write("<mime>\n");
+ for (Iterator i = mappings.keySet().iterator(); i.hasNext();) {
+ String ext = (String) i.next();
+ String type = (String) mappings.get(ext);
+
+ out.write(" <mime-mapping>\n");
+ out.write(" <extension>" + ext + "</extension>\n");
+ out.write(" <mime-type>" + type + "</mime-type>\n");
+ out.write(" </mime-mapping>\n");
+ }
+ out.write("</mime>");
+ }
+
+ private static HashMap parseApacheHttpdMime(String location) throws IOException {
+ HashMap mappings = new HashMap();
+ BufferedReader f = new BufferedReader(new FileReader(location));
+ String line;
+ while ((line = f.readLine()) != null) {
+ int startComment = line.indexOf('#');
+ if (startComment >= 0) {
+ line = line.substring(0, startComment);
+ }
+ line = line.trim();
+ String[] parsedLine = line.split(" |\\t");
+ if (parsedLine.length >= 2) {
+ for (int i = 1; i < parsedLine.length; i++) {
+ if (parsedLine[i].length() > 0) {
+ mappings.put(parsedLine[i], parsedLine[0]);
+ }
+ }
+ }
+ }
+ return mappings;
+ }
+
+ private static void convertApacheHttpdMimeToXml(String source, String destination) throws IOException {
+ HashMap mappings = parseApacheHttpdMime(source);
+ BufferedWriter output = new BufferedWriter(new FileWriter(destination));
+ writeMappingAsXml(mappings, output);
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length != 2) {
+ System.out.println("Convert Apache httpd mime file to a xml file");
+ System.out.println("Usage: java org.apache.xindice.webadmin.util.MimeTable httpdfile xmlfile");
+ System.exit(1);
+ }
+
+ convertApacheHttpdMimeToXml(args[0], args[1]);
+ System.out.println("Converted " + args[0] + " to " + args[1]);
+ }
+}
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlCollectionViewer.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlCollectionViewer.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlCollectionViewer.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlCollectionViewer.java Thu May 24 18:43:39 2007
@@ -36,17 +36,12 @@
public interface HtmlCollectionViewer {
/**
- * Role identifying Component
- */
- String ROLE = HtmlCollectionViewer.class.getName();
-
- /**
- * executes request to a collection.
+ * Executes request to a collection.
*
* @param req request from servlet.
* @param res servlet response.
* @param col requested collection (not null).
*/
- public void execute(HttpServletRequest req, HttpServletResponse res,
- Collection col) throws ServletException, IOException;
+ public void execute(HttpServletRequest req, HttpServletResponse res, Collection col)
+ throws ServletException, IOException;
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlCollectionViewer.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlDatabaseViewer.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlDatabaseViewer.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlDatabaseViewer.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlDatabaseViewer.java Thu May 24 18:43:39 2007
@@ -0,0 +1,39 @@
+/*
+ * 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.xindice.webadmin.viewer;
+
+import org.apache.xindice.core.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+import java.io.IOException;
+
+/**
+ * Xindice Html Database Interface Component.
+ */
+public interface HtmlDatabaseViewer {
+
+ /**
+ * executes request to a collection.
+ *
+ * @param req request from servlet.
+ * @param res servlet response.
+ */
+ public void execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException;
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlDatabaseViewer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlDatabaseViewer.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlResourceViewer.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlResourceViewer.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlResourceViewer.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlResourceViewer.java Thu May 24 18:43:39 2007
@@ -34,19 +34,15 @@
* @version $Id$
*/
public interface HtmlResourceViewer {
-
- /** Role identifying Component */
- String ROLE = HtmlResourceViewer.class.getName();
-
+
/**
* executes request to a resource.
*
* @param req request from servlet.
* @param res servlet response.
- * @param parentCol parent collection of the requested resource (not null).
+ * @param col parent collection of the requested resource (not null).
* @param resourceName name of the requested resource.
*/
- public void execute(HttpServletRequest req, HttpServletResponse res,
- Collection parentCol, String resourceName)
+ public void execute(HttpServletRequest req, HttpServletResponse res, Collection col, String resourceName)
throws ServletException, IOException;
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/HtmlResourceViewer.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date