| /* |
| * Copyright 2004-2005 The Apache Software Foundation or its licensors, |
| * as applicable. |
| * |
| * 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.jackrabbit.webdav.version.report; |
| |
| import org.apache.jackrabbit.webdav.DavException; |
| import org.apache.jackrabbit.webdav.DavServletResponse; |
| import org.apache.jackrabbit.webdav.version.DeltaVConstants; |
| import org.apache.jackrabbit.webdav.version.DeltaVResource; |
| import org.apache.jackrabbit.webdav.xml.DomUtil; |
| import org.apache.jackrabbit.webdav.xml.Namespace; |
| import org.apache.jackrabbit.webdav.xml.XmlSerializable; |
| import org.apache.log4j.Logger; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| import java.util.HashMap; |
| |
| /** |
| * <code>ReportType</code>... |
| */ |
| public class ReportType implements DeltaVConstants, XmlSerializable { |
| |
| private static Logger log = Logger.getLogger(ReportType.class); |
| |
| private static final HashMap types = new HashMap(); |
| |
| public static final ReportType VERSION_TREE = register(XML_VERSION_TREE, NAMESPACE, VersionTreeReport.class); |
| public static final ReportType EXPAND_PROPERTY = register(XML_EXPAND_PROPERTY, NAMESPACE, ExpandPropertyReport.class); |
| public static final ReportType LOCATE_BY_HISTORY = register(XML_LOCATE_BY_HISTORY, NAMESPACE, LocateByHistoryReport.class); |
| |
| private final String key; |
| private final String localName; |
| private final Namespace namespace; |
| private final Class reportClass; |
| |
| /** |
| * Private constructor |
| * |
| * @see ReportType#register(String, org.apache.jackrabbit.webdav.xml.Namespace, Class) |
| */ |
| private ReportType(String localName, Namespace namespace, String key, Class reportClass) { |
| this.localName = localName; |
| this.namespace = namespace; |
| this.key = key; |
| this.reportClass = reportClass; |
| } |
| |
| /** |
| * Creates a new {@link Report} with this type. |
| * |
| * @return |
| * @throws DavException |
| */ |
| public Report createReport(DeltaVResource resource, ReportInfo info) throws DavException { |
| try { |
| Report report = (Report) reportClass.getConstructor(new Class[0]).newInstance(new Object[0]); |
| report.init(resource, info); |
| return report; |
| } catch (Exception e) { |
| // should never occur |
| throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to register Report."); |
| } |
| } |
| |
| /** |
| * Returns an Xml element representing this report type. It may be used to |
| * build the body for a REPORT request. |
| * |
| * @param document |
| * @return Xml representation |
| * @see XmlSerializable#toXml(org.w3c.dom.Document) |
| */ |
| public Element toXml(Document document) { |
| return DomUtil.createElement(document, localName, namespace); |
| } |
| |
| /** |
| * Returns true if this <code>ReportType</code> is requested by the given |
| * <code>ReportInfo</code> |
| * |
| * @param reqInfo |
| * @return |
| */ |
| public boolean isRequestedReportType(ReportInfo reqInfo) { |
| if (reqInfo != null) { |
| return getReportName().equals(reqInfo.getReportName()); |
| } |
| return false; |
| } |
| |
| /** |
| * Return the qualified name of this <code>ReportType</code>. |
| * |
| * @return qualified name |
| */ |
| public String getReportName() { |
| return key; |
| } |
| |
| /** |
| * |
| * @return |
| */ |
| public String getLocalName() { |
| return localName; |
| } |
| |
| /** |
| * |
| * @return |
| */ |
| public Namespace getNamespace() { |
| return namespace; |
| } |
| |
| /** |
| * Register the report type with the given name, namespace and class, that can |
| * run that report. |
| * |
| * @param localName |
| * @param namespace |
| * @param reportClass |
| * @return |
| * @throws IllegalArgumentException if either parameter is <code>null</code> or |
| * if the given class does not implement the {@link Report} interface or if |
| * it does not provide an empty constructor. |
| */ |
| public static ReportType register(String localName, Namespace namespace, Class reportClass) { |
| if (localName == null || namespace == null || reportClass == null) { |
| throw new IllegalArgumentException("A ReportType cannot be registered with a null name, namespace or report class"); |
| } |
| |
| String key = DomUtil.getQualifiedName(localName, namespace); |
| if (types.containsKey(key)) { |
| return (ReportType) types.get(key); |
| } else { |
| // test if this report class has an empty constructor and implements Report interface |
| boolean isValidClass = false; |
| Class[] interfaces = reportClass.getInterfaces(); |
| for (int i = 0; i < interfaces.length && !isValidClass; i++) { |
| isValidClass = (interfaces[i] == Report.class); |
| } |
| if (!isValidClass) { |
| throw new IllegalArgumentException("The specified report class must implement the Report interface."); |
| } |
| |
| try { |
| reportClass.getConstructor(new Class[0]); |
| } catch (NoSuchMethodException e) { |
| throw new IllegalArgumentException("The specified report class must provide a default constructor."); |
| } |
| |
| ReportType type = new ReportType(localName, namespace, key, reportClass); |
| types.put(key, type); |
| return type; |
| } |
| } |
| |
| /** |
| * Return the <code>ReportType</code> requested by the given report info object. |
| * |
| * @param reportInfo |
| * @return the requested <code>ReportType</code> |
| * @throws IllegalArgumentException if the reportInfo is <code>null</code> or |
| * if the requested report type has not been registered yet. |
| */ |
| public static ReportType getType(ReportInfo reportInfo) { |
| if (reportInfo == null) { |
| throw new IllegalArgumentException("ReportInfo must not be null."); |
| } |
| String key = reportInfo.getReportName(); |
| if (types.containsKey(key)) { |
| return (ReportType) types.get(key); |
| } else { |
| throw new IllegalArgumentException("The request report '"+key+"' has not been registered yet."); |
| } |
| } |
| } |