| /* |
| * 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; |
| //florent import org.apache.lenya.cms.publication.Node; |
| import org.apache.lenya.cms.repository.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; |
| } |
| |
| } |