blob: 8a9039e8f311966de2e70936f8c80bf9d89fd009 [file] [log] [blame]
/*
* 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.lenya.cms.publication;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.util.Assert;
import org.apache.lenya.xml.Schema;
/**
* Resource type.
*
* @version $Id:$
*/
public class ResourceTypeImpl extends AbstractLogEnabled implements Configurable, ThreadSafe,
ResourceType, Serviceable {
/**
* The default sample name.
*/
public static final String DEFAULT_SAMPLE_NAME = "Default Sample";
protected static final String ATTRIBUTE_URI = "uri";
protected static final String ATTRIBUTE_NAME = "name";
protected static final String ELEMENT_SCHEMA = "schema";
protected static final String ATTRIBUTE_NAMESPACE = "namespace";
protected static final String ELEMENT_REWRITE_ATTRIBUTE = "link-attribute";
protected static final String ATTRIBUTE_XPATH = "xpath";
protected static final String ELEMENT_SAMPLES = "samples";
protected static final String ELEMENT_SAMPLE = "sample";
protected static final String ATTRIBUTE_MIME_TYPE = "mime-type";
protected static final String ELEMENT_FORMAT = "format";
protected static final String ELEMENT_EXPIRES = "expires";
protected static final String ATTRIBUTE_SECONDS = "seconds";
private Schema schema = null;
private String[] linkAttributeXPaths;
private Map samples;
private String samplesUri = null;
private Map formats = new HashMap();
private long expires = 0;
private String name;
private ServiceManager manager;
/**
* A format.
*/
public static class Format {
private String uri;
/**
* @param uri The uri.
*/
public Format(String uri) {
Assert.notNull("uri", uri);
this.uri = uri;
}
/**
* @return The uri.
*/
public String getURI() {
return this.uri;
}
}
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
*/
public void configure(Configuration config) throws ConfigurationException {
try {
Configuration schemaConf = config.getChild(ELEMENT_SCHEMA, false);
if (schemaConf != null) {
String uri = schemaConf.getAttribute(ATTRIBUTE_URI);
String language = schemaConf.getAttribute(ATTRIBUTE_NAMESPACE);
this.schema = new Schema(language, uri);
}
// determine the sample content locations.
Configuration samplesFileConf = config.getChild(ELEMENT_SAMPLES, false);
if (samplesFileConf != null) {
this.samplesUri = samplesFileConf.getAttribute(ATTRIBUTE_URI);
}
else {
this.samples = loadSamples(config);
}
Configuration[] rewriteAttributeConfigs = config.getChildren(ELEMENT_REWRITE_ATTRIBUTE);
List xPaths = new ArrayList();
for (int i = 0; i < rewriteAttributeConfigs.length; i++) {
String xPath = rewriteAttributeConfigs[i].getAttribute(ATTRIBUTE_XPATH);
xPaths.add(xPath);
}
this.linkAttributeXPaths = (String[]) xPaths.toArray(new String[xPaths.size()]);
Configuration[] formatConfigs = config.getChildren(ELEMENT_FORMAT);
for (int i = 0; i < formatConfigs.length; i++) {
String name = formatConfigs[i].getAttribute(ATTRIBUTE_NAME);
String uri = formatConfigs[i].getAttribute(ATTRIBUTE_URI);
this.formats.put(name, new Format(uri));
}
Configuration expiresConf = config.getChild(ELEMENT_EXPIRES, false);
if (expiresConf != null) {
this.expires = expiresConf.getAttributeAsLong(ATTRIBUTE_SECONDS);
}
} catch (Exception e) {
throw new ConfigurationException("Configuring resource type failed: ", e);
}
}
protected Map loadSamples(Configuration samplesParentConfig) throws ConfigurationException {
Configuration[] samplesConf = samplesParentConfig.getChildren(ELEMENT_SAMPLE);
Map samples = new LinkedHashMap();
for (int i = 0; i < samplesConf.length; i++) {
String name = samplesConf[i].getAttribute(ATTRIBUTE_NAME, DEFAULT_SAMPLE_NAME);
String mimeType = samplesConf[i].getAttribute(ATTRIBUTE_MIME_TYPE);
String uri = samplesConf[i].getAttribute(ATTRIBUTE_URI);
samples.put(name, new Sample(name, mimeType, uri));
}
return samples;
}
protected Configuration readConfiguration(String uri) throws ConfigurationException {
Configuration config;
DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
SourceResolver resolver = null;
Source source = null;
try {
resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
source = resolver.resolveURI(uri);
config = builder.build(source.getInputStream());
}
catch (Exception e) {
throw new ConfigurationException("Loading samples from URI [" + uri + "] failed: ", e);
}
finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
this.manager.release(resolver);
}
}
return config;
}
public Date getExpires() {
Date date = new Date();
date.setTime(date.getTime() + this.expires * 1000l);
return date;
}
public Schema getSchema() {
return this.schema;
}
public String[] getLinkAttributeXPaths() {
return this.linkAttributeXPaths;
}
protected Map getSamples() {
if (this.samplesUri == null) {
return this.samples;
}
else {
try {
Configuration samplesConfig = readConfiguration(this.samplesUri);
return loadSamples(samplesConfig);
} catch (ConfigurationException e) {
throw new RuntimeException(e);
}
}
}
public String[] getSampleNames() {
Set names = getSamples().keySet();
return (String[]) names.toArray(new String[names.size()]);
}
public Sample getSample(String name) {
Map samples = getSamples();
if (!samples.containsKey(name)) {
throw new IllegalArgumentException("No sample with name [" + name + "] found.");
}
return (Sample) samples.get(name);
}
public void setName(String name) {
Assert.notNull("name", name);
this.name = name;
}
public String getName() {
return this.name;
}
public String[] getFormats() {
Set names = this.formats.keySet();
return (String[]) names.toArray(new String[names.size()]);
}
public String getFormatURI(String format) {
if (!this.formats.containsKey(format)) {
throw new RuntimeException("The resource type [" + getName()
+ "] does not support the format [" + format + "].");
}
return ((Format) this.formats.get(format)).getURI();
}
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
}
}