blob: 6bb1d423140c56ae0c9252c08df781e4708fc99a [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.site.usecases;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.cocoon.processing.ProcessInfoProvider;
import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.lenya.ac.Identity;
import org.apache.lenya.ac.User;
import org.apache.lenya.cms.metadata.MetaData;
import org.apache.lenya.cms.metadata.MetaDataException;
import org.apache.lenya.cms.metadata.dublincore.DublinCore;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentManager;
import org.apache.lenya.cms.publication.Node;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.ResourceType;
import org.apache.lenya.cms.publication.ResourceTypeResolver;
import org.apache.lenya.cms.publication.URLInformation;
import org.apache.lenya.cms.site.SiteStructure;
import org.apache.lenya.cms.usecase.AbstractUsecase;
import org.apache.lenya.cms.usecase.UsecaseException;
/**
* <p>
* Abstract superclass for usecases to create a document.
* </p>
* <p>
* You can pass the following parameters into the usecase:
* </p>
* <ul>
* <li><strong>path</strong> - the path of the document to create (optional)</li>
* </ul>
*
* @version $Id$
*/
public abstract class Create extends AbstractUsecase {
protected static final String RESOURCE_TYPES = "resourceTypes";
protected static final String LANGUAGE = "language";
protected static final String LANGUAGES = "languages";
protected static final String PATH = "path";
protected static final String NODE_NAME = "nodeName";
protected static final String VISIBLEINNAV = "visibleInNav";
protected static final String SAMPLE = "sample";
protected static final String SAMPLES = "samples";
private DocumentManager documentManager;
private ResourceTypeResolver resourceTypeResolver;
/**
* @see org.apache.lenya.cms.usecase.AbstractUsecase#doCheckPreconditions()
*/
protected void doCheckPreconditions() throws Exception {
super.doCheckPreconditions();
if (!getArea().equals(Publication.AUTHORING_AREA)) {
addErrorMessage("This usecase can only be invoked in the authoring area!");
}
}
/**
* @see org.apache.lenya.cms.usecase.AbstractUsecase#getNodesToLock()
*/
protected Node[] getNodesToLock() throws UsecaseException {
try {
SiteStructure structure = getPublication().getArea(getArea()).getSite();
Node[] nodes = { structure };
return nodes;
} catch (Exception e) {
throw new UsecaseException(e);
}
}
/**
* @see org.apache.lenya.cms.usecase.AbstractUsecase#doCheckExecutionConditions()
*/
protected void doCheckExecutionConditions() throws Exception {
String navigationTitle = getDublinCoreParameter(DublinCore.ELEMENT_TITLE);
if (navigationTitle.trim().equals("")) {
addErrorMessage("missing-navigation-title");
}
if (getInitialDocument() == null) {
String[] samples = (String[]) getParameter(SAMPLES);
String sample = getParameterAsString(SAMPLE);
if (samples != null && samples.length > 1 && (sample == null || sample.equals(""))) {
addErrorMessage("missing-page-layout");
}
}
if (isPathValid()) {
String path = getNewDocumentPath();
SiteStructure site = getPublication().getArea(getArea()).getSite();
if (!createVersion() && site.contains(path)) {
String[] params = { path };
addErrorMessage("path-already-exists", params);
}
}
String doctypeName = getDocumentTypeName();
if (getParameterAsString(SAMPLE) == null && doctypeName != null) {
initSampleParameters();
}
}
/**
* This method is used by {@link #doCheckExecutionConditions()} to check if the path entered by
* the user is valid. If not, checking the existence of the new document in the site structure
* is omitted because this operation could cause errors.
* @return A boolean value.
*/
protected boolean isPathValid() {
return true;
}
/**
* @see org.apache.lenya.cms.usecase.AbstractUsecase#doExecute()
*/
protected void doExecute() throws Exception {
super.doExecute();
// create new document
ResourceType resourceType = null;
String language = getParameterAsString(LANGUAGE);
Document initialDocument = getInitialDocument();
Document document;
String title = getDublinCoreParameter(DublinCore.ELEMENT_TITLE).trim();
if (createVersion()) {
document = documentManager.addVersion(initialDocument, getArea(), language, true);
document.getLink().setLabel(title);
} else {
if (initialDocument == null) {
resourceType = getResourceTypeResolver().getResourceType(getDocumentTypeName());
String sampleName = getParameterAsString(SAMPLE, resourceType.getSampleNames()[0]);
ResourceType.Sample sample = resourceType.getSample(sampleName);
document = documentManager.add(resourceType, sample.getUri(),
getPublication(), getArea(), getNewDocumentPath(), language,
getSourceExtension(), title, getVisibleInNav());
document.setMimeType(sample.getMimeType());
} else {
document = documentManager.add(initialDocument, getArea(), getNewDocumentPath(),
language, getSourceExtension(), title, getVisibleInNav());
}
}
setMetaData(document);
// the location to navigate to after completion of usecase
setDefaultTargetURL(document.getCanonicalWebappURL());
}
protected String getDublinCoreParameter(String name) {
Object param = getParameter(DUBLIN_CORE_PREFIX + name);
if (param != null && getParameter(DUBLIN_CORE_PREFIX + name).getClass().isArray()) {
String[] values = (String[]) getParameter(DUBLIN_CORE_PREFIX + name);
StringBuffer paramValue = new StringBuffer();
for (int i = 0; i < values.length; i++) {
String value = values[i];
if (i > 0)
paramValue.append(',').append(value);
else
paramValue.append(value);
}
return paramValue.toString();
}
return getParameterAsString(DUBLIN_CORE_PREFIX + name, null);
}
protected void setDublinCoreParameter(String name, String value) {
setParameter(DUBLIN_CORE_PREFIX + name, value);
}
protected abstract boolean createVersion();
/**
* @return the extension to use for the document source.
*/
protected abstract String getSourceExtension();
/**
* @return the name of the document being created in the usecase
*/
protected abstract String getNewDocumentName();
/**
* @return the id of the new document being created in the usecase
*/
protected abstract String getNewDocumentPath();
/**
* If the document created in the usecase shall have initial contents copied from an existing
* document, construct that document in this method.
*
* @return A document.
*/
protected Document getInitialDocument() {
return null;
}
/**
* @return The type of the created document.
*/
protected abstract String getDocumentTypeName();
protected static final String DUBLIN_CORE_PREFIX = "dublincore.";
/**
* Sets the meta data of the created document.
*
* @param document The document.
* @throws MetaDataException if an error occurs.
*/
protected void setMetaData(Document document) throws MetaDataException {
if (document == null)
throw new IllegalArgumentException("parameter document may not be null");
MetaData dcMetaData = document.getMetaData(DublinCore.DC_NAMESPACE);
String[] dcKeys = dcMetaData.getAvailableKeys();
for (int i = 0; i < dcKeys.length; i++) {
String param = getDublinCoreParameter(dcKeys[i]);
if (param != null) {
dcMetaData.setValue(dcKeys[i], param);
}
}
}
/**
* @see org.apache.lenya.cms.usecase.AbstractUsecase#initParameters()
*/
protected void initParameters() {
super.initParameters();
ProcessInfoProvider process = (ProcessInfoProvider) WebAppContextUtils
.getCurrentWebApplicationContext().getBean(ProcessInfoProvider.ROLE);
HttpServletRequest request = process.getRequest();
HttpSession session = request.getSession(false);
Identity identity = (Identity) session.getAttribute(Identity.class.getName());
User user = identity.getUser();
if (user != null) {
setDublinCoreParameter(DublinCore.ELEMENT_CREATOR, user.getId());
} else {
setDublinCoreParameter(DublinCore.ELEMENT_CREATOR, "");
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
setDublinCoreParameter(DublinCore.ELEMENT_DATE, format.format(new GregorianCalendar()
.getTime()));
String doctypeName = getDocumentTypeName();
if (doctypeName != null) {
initSampleParameters();
setParameter(RESOURCE_TYPES, Collections.EMPTY_LIST);
} else {
String[] resourceTypes = getPublication().getResourceTypeNames();
setParameter(RESOURCE_TYPES, Arrays.asList(resourceTypes));
}
}
protected void initSampleParameters() {
ResourceType resourceType = null;
try {
resourceType = getResourceTypeResolver().getResourceType(getDocumentTypeName());
String[] samples = resourceType.getSampleNames();
if (samples.length == 0) {
addErrorMessage("The resource type [" + resourceType.getName()
+ "] doesn't provide any samples!");
} else {
setParameter(SAMPLES, samples);
String presetSample = getParameterAsString(SAMPLE);
if (presetSample == null) {
setParameter(SAMPLE, samples[0]);
} else {
List sampleList = Arrays.asList(samples);
if (!sampleList.contains(presetSample)) {
getLogger().warn(
"Sample [" + presetSample + "] not defined, using default sample.");
setParameter(SAMPLE, samples[0]);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @return The source document or <code>null</code> if the usecase was not invoked on a
* document.
*/
protected Document getSourceDocument() {
Document document = null;
String url = getSourceURL();
try {
if (getSession().getUriHandler().isDocument(url)) {
document = getSession().getUriHandler().getDocument(url);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return document;
}
/**
* @return The new document.
*/
protected Document getNewDocument() {
try {
String path = getNewDocumentPath();
String language = getParameterAsString(LANGUAGE);
return getPublication().getArea(getArea()).getSite().getNode(path).getLink(language)
.getDocument();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @return The area without the "info-" prefix.
*/
public String getArea() {
URLInformation info = new URLInformation(getSourceURL());
return info.getArea();
}
/**
* @return the visibleInNav Attribute of the document being created in the usecase
*/
protected boolean getVisibleInNav() {
if (getParameterAsString(VISIBLEINNAV).equals("false")) {
return false;
}
return true;
}
protected DocumentManager getDocumentManager() {
return documentManager;
}
/**
* TODO: Bean wiring
*/
public void setDocumentManager(DocumentManager documentManager) {
this.documentManager = documentManager;
}
protected ResourceTypeResolver getResourceTypeResolver() {
return resourceTypeResolver;
}
/**
* TODO: Bean wiring
*/
public void setResourceTypeResolver(ResourceTypeResolver resourceTypeResolver) {
this.resourceTypeResolver = resourceTypeResolver;
}
}