Package org.apache.lenya.cms.site.usecases

Source Code of org.apache.lenya.cms.site.usecases.Create

/*
* 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 java.util.Map;

import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
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.Publication;
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.publication.PublicationUtil;
import org.apache.lenya.cms.publication.ResourceType;
import org.apache.lenya.cms.publication.URLInformation;
import org.apache.lenya.cms.repository.Node;
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: Create.java 571550 2007-08-31 19:18:54Z rfrovarp $
*/
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";

    /**
     * Ctor.
     */
    public Create() {
        super();
    }

    /**
     * @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.getRepositoryNode() };
            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
        DocumentManager documentManager = null;
        ServiceSelector selector = null;
        ResourceType resourceType = null;
        try {

            documentManager = (DocumentManager) this.manager.lookup(DocumentManager.ROLE);

            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) {
                    selector = (ServiceSelector) this.manager
                            .lookup(ResourceType.ROLE + "Selector");
                    resourceType = (ResourceType) selector.select(getDocumentTypeName());
                    String sampleName = getParameterAsString(SAMPLE, resourceType.getSampleNames()[0]);
                    ResourceType.Sample sample = resourceType.getSample(sampleName);
                    document = documentManager.add(getDocumentFactory(), 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());

        } finally {
            if (documentManager != null) {
                this.manager.release(documentManager);
            }
            if (selector != null) {
                if (resourceType != null) {
                    selector.release(resourceType);
                }
                this.manager.release(selector);
            }
        }
    }

    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();

        Map objectModel = ContextHelper.getObjectModel(getContext());
        Request request = ObjectModelHelper.getRequest(objectModel);
        Session 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() {
        ServiceSelector selector = null;
        ResourceType resourceType = null;
        try {
            selector = (ServiceSelector) this.manager.lookup(ResourceType.ROLE + "Selector");
            resourceType = (ResourceType) selector.select(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);
        } finally {
            if (selector != null) {
                if (resourceType != null) {
                    selector.release(resourceType);
                }
                this.manager.release(selector);
            }
        }
    }

    /**
     * @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 (getDocumentFactory().isDocument(url)) {
                document = getDocumentFactory().getFromURL(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();
    }

    /**
     * Access to the current publication. Use this when the publication is not
     * yet known in the usecase: e.g. when creating a global asset. When adding
     * a resource or a child to a document, access the publication via that
     * document's interface instead.
     *
     * @return the publication in which the use-case is being executed
     */
    protected Publication getPublication() {
        try {
            return PublicationUtil.getPublicationFromUrl(this.manager, getDocumentFactory(),
                    getSourceURL());
        } catch (PublicationException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @return the visibleInNav Attribute of the document being created in the
     *         usecase
     */
    protected boolean getVisibleInNav() {
        if (getParameterAsString(VISIBLEINNAV).equals("false")) {
            return false;
        }
        return true;
    }

}
TOP

Related Classes of org.apache.lenya.cms.site.usecases.Create

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.