All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectstyle.cayenne.dataview.DataView Maven / Gradle / Ivy

Go to download

Cayenne Object Persistence Framework including all dependencies.

The newest version!
/* ====================================================================
*
* The ObjectStyle Group Software License, version 1.1
* ObjectStyle Group - http://objectstyle.org/
* 
* Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
* of the software. All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
* 
* 3. The end-user documentation included with the redistribution, if any,
*    must include the following acknowlegement:
*    "This product includes software developed by independent contributors
*    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
* 
* 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
*    or promote products derived from this software without prior written
*    permission. For written permission, email
*    "andrus at objectstyle dot org".
* 
* 5. Products derived from this software may not be called "ObjectStyle"
*    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
*    names without prior written permission.
* 
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
* 
* This software consists of voluntary contributions made by many
* individuals and hosted on ObjectStyle Group web site.  For more
* information on the ObjectStyle Group, please see
* .
*/
package org.objectstyle.cayenne.dataview;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.text.Format;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.math.NumberUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.objectstyle.cayenne.DataObject;
import org.objectstyle.cayenne.map.EntityResolver;
import org.objectstyle.cayenne.map.ObjAttribute;
import org.objectstyle.cayenne.map.ObjEntity;
import org.objectstyle.cayenne.map.ObjRelationship;

/**
 * A root of the view configuration hierarchy. Contains a number of ObjEntityViews.
 * 
 * @since 1.1
 * @author Andriy Shapochka
 */
public class DataView {

    private Locale locale = Locale.US;
    
    //Data type definitions
    private DataTypeSpec dataTypeSpec = new DataTypeSpec();
    
    //Format definitions
    private FormatFactory formatFactory = new FormatFactory();
    
    //ObjEntity lookup
    private EntityResolver entityResolver;

    private Map objEntityViews = new TreeMap();
    private Set lookupEntityViewFields;
    private LookupCache lookupCache = new LookupCache();
    private EventDispatcher fieldValueChangeDispatcher;
    
    //used internally to resolve field lookup dependencies
    private Map lookupReferenceTable;

    public DataView() {
    }

    public EntityResolver getEntityResolver() {
        return entityResolver;
    }

    public void setEntityResolver(EntityResolver entityResolver) {
        Validate.notNull(entityResolver);
        this.entityResolver = entityResolver;
    }

    public void load(File[] xmlSources) throws IOException {
        Validate.noNullElements(xmlSources);
        SAXBuilder builder = new SAXBuilder();
        Document[] documents = new Document[xmlSources.length];
        for (int i = 0; i < xmlSources.length; i++) {
            try {
                documents[i] = builder.build(xmlSources[i]);
            }
            catch (JDOMException ex) {
                ex.printStackTrace();
            }
        }
        load(documents);
    }

    public void load(URL[] xmlSources) throws IOException {
        Validate.noNullElements(xmlSources);
        SAXBuilder builder = new SAXBuilder();
        Document[] documents = new Document[xmlSources.length];
        for (int i = 0; i < xmlSources.length; i++) {
            try {
                documents[i] = builder.build(xmlSources[i]);
            }
            catch (JDOMException ex) {
                ex.printStackTrace();
            }
        }
        load(documents);
    }

    public void load(Reader[] xmlSources) throws IOException {
        Validate.noNullElements(xmlSources);
        SAXBuilder builder = new SAXBuilder();
        Document[] documents = new Document[xmlSources.length];
        for (int i = 0; i < xmlSources.length; i++) {
            try {
                documents[i] = builder.build(xmlSources[i]);
            }
            catch (JDOMException ex) {
                ex.printStackTrace();
            }
        }
        load(documents);
    }

    public void load(InputStream[] xmlSources) throws IOException {
        Validate.noNullElements(xmlSources);
        SAXBuilder builder = new SAXBuilder();
        Document[] documents = new Document[xmlSources.length];
        for (int i = 0; i < xmlSources.length; i++) {
            try {
                documents[i] = builder.build(xmlSources[i]);
            }
            catch (JDOMException ex) {
                ex.printStackTrace();
            }
        }
        load(documents);
    }

    public void load(Document[] views) {
        Validate.noNullElements(views);
        lookupReferenceTable = new HashMap();
        for (int i = 0; i < views.length; i++) {
            Element root = views[i].getRootElement();
            List entityViews = root.getChildren("obj-entity-view");
            for (Iterator j = entityViews.iterator(); j.hasNext();) {
                Element entityViewElement = (Element) j.next();
                loadEntityView(entityViewElement);
            }
        }
        resolveLookupReferences();
        lookupReferenceTable = null;
    }

    private void resolveLookupReferences() {
        lookupEntityViewFields = new HashSet();
        for (Iterator i = lookupReferenceTable.entrySet().iterator(); i.hasNext();) {
            Map.Entry entry = (Map.Entry) i.next();
            ObjEntityViewField field = (ObjEntityViewField) entry.getKey();
            String[] lookupDescriptor = (String[]) entry.getValue();
            ObjEntityView lookupEntityView = getObjEntityView(lookupDescriptor[0]);
            ObjEntityViewField lookupField = lookupEntityView
                    .getField(lookupDescriptor[1]);
            field.setLookupField(lookupField);
            lookupEntityViewFields.add(lookupField);
        }
    }

    private void loadEntityView(Element element) {
        String name = element.getAttributeValue("name");
        Validate.isTrue(name != null && !objEntityViews.containsKey(name));
        String objEntityName = element.getAttributeValue("obj-entity-name");
        Validate.notNull(objEntityName);
        ObjEntity objEntity = entityResolver.getObjEntity(objEntityName);
        ObjEntityView entityView = new ObjEntityView();
        entityView.setName(name);
        entityView.setObjEntity(objEntity);
        objEntityViews.put(name, entityView);
        entityView.setOwner(this);
        List fields = element.getChildren("field");
        for (Iterator i = fields.iterator(); i.hasNext();) {
            Element fieldElement = (Element) i.next();
            loadField(entityView, fieldElement);
        }
    }

    private void loadField(ObjEntityView entityView, Element element) {
        String name = element.getAttributeValue("name");
        ObjEntityViewField field = new ObjEntityViewField();
        field.setName(name);
        String prefIndex = element.getAttributeValue("pref-index");
        field.setPreferredIndex(NumberUtils.toInt(prefIndex, -1));
        entityView.insertField(field);

        String calcType = element.getAttributeValue("calc-type");
        Validate.notNull(calcType);
        CalcTypeEnum fieldCalcType = CalcTypeEnum.getEnum(calcType);
        Validate.isTrue(
                CalcTypeEnum.NO_CALC_TYPE.equals(fieldCalcType)
                        || CalcTypeEnum.LOOKUP_TYPE.equals(fieldCalcType),
                "Calc Type not supported yet: ",
                fieldCalcType);
        field.setCalcType(fieldCalcType);

        ObjEntity objEntity = entityView.getObjEntity();

        if (CalcTypeEnum.NO_CALC_TYPE.equals(fieldCalcType)) {
            String objAttributeName = element.getAttributeValue("obj-attribute-name");
            Validate.notNull(objAttributeName);
            ObjAttribute objAttribute = (ObjAttribute) objEntity
                    .getAttribute(objAttributeName);
            field.setObjAttribute(objAttribute);
        }
        else if (CalcTypeEnum.LOOKUP_TYPE.equals(fieldCalcType)) {
            String objRelationshipName = element
                    .getAttributeValue("obj-relationship-name");
            Validate.notNull(objRelationshipName);
            ObjRelationship objRelationship = (ObjRelationship) objEntity
                    .getRelationship(objRelationshipName);
            field.setObjRelationship(objRelationship);
            Element lookupElement = element.getChild("lookup");
            Validate.notNull(lookupElement);
            String lookupEntityView = lookupElement
                    .getAttributeValue("obj-entity-view-name");
            Validate.notNull(lookupEntityView);
            String lookupEntityField = lookupElement.getAttributeValue("field-name");
            Validate.notNull(lookupEntityField);
            String[] lookupDescriptor = new String[] {
                    lookupEntityView, lookupEntityField
            };
            lookupReferenceTable.put(field, lookupDescriptor);
        }

        String dataType = element.getAttributeValue("data-type");
        Validate.notNull(dataType);
        field.setDataType(dataTypeSpec.getDataType(dataType));

        String editable = element.getAttributeValue("editable");
        field.setEditable(BooleanUtils.toBoolean(editable));

        String visible = element.getAttributeValue("visible");
        field.setVisible(BooleanUtils.toBoolean(visible));

        Element captionElement = element.getChild("caption");
        if (captionElement != null)
            field.setCaption(StringUtils.stripToEmpty(captionElement.getText()));

        Element editFormatElement = element.getChild("edit-format");
        if (editFormatElement != null) {
            String formatClassName = editFormatElement.getAttributeValue("class");
            Validate.notNull(formatClassName);
            Class formatClass;
            try {
                formatClass = Class.forName(formatClassName);
                Map parameters = DataView.childrenToMap(editFormatElement);
                Format format = formatFactory.createFormat(
                        formatClass,
                        locale,
                        parameters);
                field.setEditFormat(format);
            }
            catch (ClassNotFoundException ex) {
            }
        }

        Element displayFormatElement = element.getChild("display-format");
        if (displayFormatElement != null) {
            String formatClassName = displayFormatElement.getAttributeValue("class");
            Validate.notNull(formatClassName);
            Class formatClass;
            try {
                formatClass = Class.forName(formatClassName);
                Map parameters = DataView.childrenToMap(displayFormatElement);
                Format format = formatFactory.createFormat(
                        formatClass,
                        locale,
                        parameters);
                field.setDisplayFormat(format);
            }
            catch (ClassNotFoundException ex) {
            }
        }

        Element defaultValueElement = element.getChild("default-value");
        if (defaultValueElement != null) {
            String defaultValueStr = StringUtils.stripToEmpty(defaultValueElement
                    .getText());
            Object defaultValue = dataTypeSpec.create(
                    field.getDataType(),
                    defaultValueStr);
            field.setDefaultValue(defaultValue);
        }
    }

    public Set getObjEntityViewNames() {
        return Collections.unmodifiableSet(objEntityViews.keySet());
    }

    public Collection getObjEntityViews() {
        return Collections.unmodifiableCollection(objEntityViews.values());
    }

    public ObjEntityView getObjEntityView(String viewName) {
        return (ObjEntityView) objEntityViews.get(viewName);
    }

    public LookupCache getLookupCache() {
        return lookupCache;
    }

    public void setLookupCache(LookupCache lookupCache) {
        Validate.notNull(lookupCache);
        this.lookupCache = lookupCache;
    }

    public Set getLookupObjEntityViewFields() {
        return Collections.unmodifiableSet(lookupEntityViewFields);
    }

    public Locale getLocale() {
        return locale;
    }

    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    public DataTypeSpec getDataTypeSpec() {
        return dataTypeSpec;
    }

    public void setDataTypeSpec(DataTypeSpec dataTypeSpec) {
        this.dataTypeSpec = dataTypeSpec;
    }

    public FormatFactory getFormatFactory() {
        return formatFactory;
    }

    public void setFormatFactory(FormatFactory formatFactory) {
        this.formatFactory = formatFactory;
    }

    private static Map childrenToMap(Element element) {
        List children = element.getChildren();
        if (children.isEmpty())
            return Collections.EMPTY_MAP;
        else {
            Map map = new HashMap(children.size());
            for (Iterator i = children.iterator(); i.hasNext();) {
                Element child = (Element) i.next();
                map.put(child.getName(), StringUtils.stripToNull(child.getText()));
            }
            return map;
        }
    }

    public void addFieldValueChangeListener(FieldValueChangeListener listener) {
        fieldValueChangeDispatcher = EventDispatcher.add(
                fieldValueChangeDispatcher,
                listener);
    }

    public void removeFieldValueChangeListener(FieldValueChangeListener listener) {
        fieldValueChangeDispatcher = EventDispatcher.remove(
                fieldValueChangeDispatcher,
                listener);
    }

    public void clearFieldValueChangeListeners() {
        if (fieldValueChangeDispatcher != null) {
            fieldValueChangeDispatcher.clear();
            fieldValueChangeDispatcher = null;
        }
    }

    public void fireFieldValueChangeEvent(
            ObjEntityViewField source,
            DataObject modifiedObject,
            Object oldValue,
            Object newValue) {
        if (fieldValueChangeDispatcher != null && source.getRootOwner() == this) {
            fieldValueChangeDispatcher.dispatch(new FieldValueChangeEvent(
                    source,
                    modifiedObject,
                    oldValue,
                    newValue));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy