org.apache.cocoon.forms.formmodel.library.Library.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.cocoon.forms.formmodel.library.Library.java

Source

/*
 * Copyright 1999-2005 The Apache Software Foundation.
 * 
 * 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.cocoon.forms.formmodel.library;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.forms.FormsConstants;
import org.apache.cocoon.forms.formmodel.WidgetDefinition;
import org.apache.cocoon.forms.formmodel.WidgetDefinitionBuilder;
import org.apache.cocoon.forms.formmodel.WidgetDefinitionBuilderContext;
import org.apache.cocoon.forms.util.DomHelper;
import org.apache.cocoon.util.location.LocationAttributes;
import org.apache.commons.lang.StringUtils;

import org.w3c.dom.Element;

/**
 * @version $Id: Library.java 372278 2006-01-25 18:24:06Z mpfingsthorn $
 */
public class Library {

    public static final String SEPARATOR = ":";

    // managed instances
    protected ServiceSelector widgetDefinitionBuilderSelector;

    // own references
    protected LibraryManager manager = null;

    // own instances
    protected Map definitions = new HashMap();
    protected Map inclusions = new HashMap();

    // shared object with dependencies
    protected Object shared = new Object();

    protected String sourceURI = null;
    protected WidgetDefinitionBuilderContext context;

    public Library(LibraryManager lm) {
        manager = lm;
        context = new WidgetDefinitionBuilderContext();
        context.setLocalLibrary(this);
    }

    public void setSourceURI(String uri) {
        sourceURI = uri;
    }

    public String getSourceURI() {
        return sourceURI;
    }

    public void setWidgetDefinitionBuilderSelector(ServiceSelector selector) {
        this.widgetDefinitionBuilderSelector = selector;
    }

    public boolean dependenciesHaveChanged() throws Exception {

        Iterator it = this.inclusions.values().iterator();
        while (it.hasNext()) {
            Dependency dep = (Dependency) it.next();
            if (!dep.isValid())
                return true;
        }

        return false;
    }

    /**
     * "Registers" a library to be referenced later under a certain key or prefix.
     * Definitions will be accessible locally through prefixing: "prefix:definitionid"
     * 
     * @param key the key 
     * @param librarysource the source of the library to be know as "key"
     * @return true if there was no such key used before, false otherwise
     */
    public boolean includeAs(String key, String librarysource) throws LibraryException {
        try {
            // library keys may not contain ":"!
            if ((!inclusions.containsKey(key) || key.indexOf(SEPARATOR) > -1)
                    && manager.getLibrary(librarysource, sourceURI) != null) {
                inclusions.put(key, new Dependency(librarysource));
                return true;
            }
            return false;
        } catch (Exception e) {
            throw new LibraryException("Could not include library '" + librarysource + "'", e);
        }

    }

    public WidgetDefinition getDefinition(String key) throws LibraryException {

        String librarykey = null;
        String definitionkey = key;

        if (key.indexOf(SEPARATOR) > -1) {
            String[] parts = StringUtils.split(key, SEPARATOR);
            librarykey = parts[0];
            definitionkey = parts[1];
            for (int i = 2; i < parts.length; i++) {
                definitionkey += SEPARATOR + parts[i];
            }
        }

        if (librarykey != null) {
            if (inclusions.containsKey(librarykey)) {
                try {
                    return manager
                            .getLibrary(((Dependency) inclusions.get(librarykey)).dependencySourceURI, sourceURI)
                            .getDefinition(definitionkey);
                } catch (Exception e) {
                    throw new LibraryException("Couldn't get Library key='" + librarykey + "' source='"
                            + inclusions.get(librarykey) + "", e);
                }
            } else {
                throw new LibraryException("Library '" + librarykey + "' does not exist! (lookup: '" + key + "')");
            }
        } else {
            return (WidgetDefinition) definitions.get(definitionkey);
        }
    }

    public void buildLibrary(Element libraryElement) throws Exception {
        sourceURI = LocationAttributes.getURI(libraryElement);
        Element widgetsElement = DomHelper.getChildElement(libraryElement, FormsConstants.DEFINITION_NS, "widgets",
                true);
        // All child elements of the widgets element are widgets
        Element[] widgetElements = DomHelper.getChildElements(widgetsElement, FormsConstants.DEFINITION_NS);
        for (int i = 0; i < widgetElements.length; i++) {
            Element widgetElement = widgetElements[i];
            WidgetDefinition widgetDefinition = buildWidgetDefinition(widgetElement);
            addDefinition(widgetDefinition);
        }
    }

    public void addDefinition(WidgetDefinition definition) throws LibraryException {
        if (definition == null)
            return;

        if (definitions.containsKey(definition.getId()))
            throw new LibraryException("Library already contains a widget with this ID!");

        // let the definition know where it comes from
        definition.setEnclosingLibrary(this);

        // add def to our list of defs
        definitions.put(definition.getId(), definition);
        manager.debug(this + ": Put definition with id: " + definition.getId());
    }

    protected WidgetDefinition buildWidgetDefinition(Element widgetDefinition) throws Exception {
        String widgetName = widgetDefinition.getLocalName();
        WidgetDefinitionBuilder builder = null;
        try {
            builder = (WidgetDefinitionBuilder) widgetDefinitionBuilderSelector.select(widgetName);
        } catch (ServiceException e) {
            throw new CascadingException(
                    "Unknown kind of widget '" + widgetName + "' at " + DomHelper.getLocation(widgetDefinition), e);
        }

        context.setSuperDefinition(null);
        String extend = DomHelper.getAttribute(widgetDefinition, "extends", null);

        if (extend != null)
            context.setSuperDefinition(getDefinition(extend));

        return builder.buildWidgetDefinition(widgetDefinition, context);
    }

    /**
     * Encapsulates a uri to designate an import plus a timestamp so previously reloaded 
     */
    public class Dependency {

        private String dependencySourceURI;
        private Object shared;

        public Dependency(String dependencySourceURI) throws Exception {
            this.dependencySourceURI = dependencySourceURI;

            Library lib = manager.getLibrary(this.dependencySourceURI, sourceURI);
            this.shared = lib.shared;
        }

        public boolean isValid() throws LibraryException {
            try {

                if (manager.libraryInCache(dependencySourceURI, sourceURI)) {
                    Library lib = manager.getLibrary(dependencySourceURI, sourceURI);

                    if (this.shared == lib.shared)
                        return true;
                }

                return false;
            } catch (Exception forward) {
                throw new LibraryException("Exception occured while checking dependency validity!", forward);
            }

        }
    }

}