/* ==================================================================== * * The ObjectStyle Group Software License, Version 1.0 * * Copyright (c) 2005 The ObjectStyle Group, * 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 the * ObjectStyle Group (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, please contact andrus@objectstyle.org. * * 5. Products derived from this software may not be called "ObjectStyle" * nor may "ObjectStyle" appear in their names without prior written * permission of the ObjectStyle Group. * * 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 on behalf of the ObjectStyle Group. For more * information on the ObjectStyle Group, please see * <http://objectstyle.org/>. * */ package org.objectstyle.wolips.wodclipse.core.woo; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.objectstyle.wolips.bindings.wod.TypeCache; import org.objectstyle.wolips.eomodeler.core.model.EOAttribute; import org.objectstyle.wolips.eomodeler.core.model.EODataSource; import org.objectstyle.wolips.eomodeler.core.model.EODataSourceFactory; import org.objectstyle.wolips.eomodeler.core.model.EODatabaseDataSource; import org.objectstyle.wolips.eomodeler.core.model.EODetailDataSource; import org.objectstyle.wolips.eomodeler.core.model.EODisplayGroupSortOrdering; import org.objectstyle.wolips.eomodeler.core.model.EOEntity; import org.objectstyle.wolips.eomodeler.core.model.EOFetchSpecification; import org.objectstyle.wolips.eomodeler.core.model.EOModelMap; import org.objectstyle.wolips.eomodeler.core.model.EOModelVerificationFailure; import org.objectstyle.wolips.eomodeler.core.model.EORelationship; import org.objectstyle.wolips.eomodeler.core.model.EOSortOrdering; import org.objectstyle.wolips.eomodeler.core.utils.IPropertyChangeSource; import org.objectstyle.wolips.wodclipse.core.completion.WodParserCache; public class DisplayGroup implements IPropertyChangeSource { public static final String NAME = "name"; public static final String CLASS_NAME = "className"; public static final String CLASS_NAME_INDEX = "classNameIndex"; public static final String CLASS_NAME_LIST = "classNameList"; public static final String QUALIFICATION_INDEX = "qualificationIndex"; public static final String QUALIFICATION_LIST = "qualificationList"; public static final String ENTITY_NAME = "entityName"; public static final String ENTITY_LIST = "entityList"; public static final String MASTER_ENTITY_NAME = "masterEntityName"; public static final String DETAIL_KEY_NAME = "detailKeyName"; public static final String DETAIL_KEY_LIST = "detailKeyList"; public static final String SORT_LIST = "sortList"; public static final String HAS_MASTER_DETAIL = "hasMasterDetail"; public static final String SORT_ORDER = "sortOrder"; public static final String SORT_ORDER_KEY = "sortOrderKey"; public static final String FETCH_SPEC_LIST = "fetchSpecList"; public static final String FETCH_SPEC_NAME = "fetchSpecName"; public static final String ENTRIES_PER_BATCH = "entriesPerBatch"; public static final String FETCHES_ON_LOAD = "fetchesOnLoad"; public static final String SELECTS_FIRST_OBJECT = "selectsFirstObject"; public static final String EDITING_CONTEXT = "editingContext"; public static final String ASCENDING = "Ascending"; public static final String DESCENDING = "Descending"; public static final String NOT_SORTED = "Not Sorted"; public static final String FETCH_SPEC_NONE = "<None>"; public static final String[] SORT_OPTIONS = new String[] { ASCENDING, DESCENDING, NOT_SORTED, }; private static final String QUALIFIER_PREFIX = "%@*"; private static final String QUALIFIER_SUFFIX = "*%@"; private static final String QUALIFIER_CONTAINS = "*%@*"; private static final String[] QUALIFICATION_LABELS = new String[] { "Prefix", "Contains", "Suffix", }; private static final String[] QUALIFICATION_FORMATS = new String[] { QUALIFIER_PREFIX, QUALIFIER_CONTAINS, QUALIFIER_SUFFIX, }; private String _originalName; private String _name = "newDisplayGroup"; private WooModel _wooModel; private int _qualificationIndex; private List<String> _entityList; private EOEntity _entity; private String _entityName; private EOEntity _masterEntity; private String _masterEntityName; private String _detailKeyName; private boolean _hasMasterDetail; private boolean _fetchesOnLoad; private String _className; private int _classNameIndex; private List<String> _classNameList; private String _qualifierFormat; private int _entriesPerBatch; private List<String> _localKeys; private boolean _selectsFirstObject; private PropertyChangeSupport _changeSupport; private EODataSource _dataSource; private EODatabaseDataSource _databaseDataSource; private EODetailDataSource _detailDataSource; private EOSortOrdering _sortOrder; private boolean _isSorted; public DisplayGroup(WooModel model) { _wooModel = model; _wooModel.getModelGroup(); _databaseDataSource = new EODatabaseDataSource(_wooModel.getModelGroup()); _detailDataSource = new EODetailDataSource(_wooModel.getModelGroup()); _dataSource = _databaseDataSource; _qualificationIndex = 0; _qualifierFormat = QUALIFICATION_FORMATS[0]; _className = "WODisplayGroup"; _classNameIndex = getClassNameList().indexOf(_className); _isSorted = false; _hasMasterDetail = false; _changeSupport = new PropertyChangeSupport(this); _sortOrder = new EODisplayGroupSortOrdering(); _selectsFirstObject = false; } public void addPropertyChangeListener(final PropertyChangeListener listener) { _changeSupport.addPropertyChangeListener(listener); } public void addPropertyChangeListener(final String name, final PropertyChangeListener listener) { _changeSupport.addPropertyChangeListener(name, listener); } protected void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) { if (oldValue != newValue || (oldValue != null && !oldValue.equals(newValue)) || (newValue != null && !newValue.equals(oldValue))) { _wooModel.markAsDirty(); _changeSupport.firePropertyChange(propertyName, oldValue, newValue); } } public String getClassName() { return _className; } public int getClassNameIndex() { return _classNameIndex; } public List<String> getClassNameList() { if (_classNameList == null) { _classNameList = new ArrayList<String>(); try { IJavaProject project = JavaCore.create(_wooModel.getProject()); IType displayGroupType = project.findType("com.webobjects.appserver.WODisplayGroup"); List<IType> subTypes = WodParserCache.getTypeCache().getSubtypesOfInProject(displayGroupType, project); for (IType type : subTypes) { _classNameList.add(type.getElementName()); } } catch (JavaModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return _classNameList; } public List<String> getDetailKeyList() { if (_masterEntity != null) { List<String> keyList = new ArrayList<String>(); Set<EORelationship> relationships = _masterEntity.getRelationships(); for (EORelationship relation : relationships) { if (relation.getToMany() != null && relation.getToMany().booleanValue()) { keyList.add(relation.getName()); } } return keyList; } return null; } public String getDetailKeyName() { return _detailKeyName; } public String getEditingContext() { return _databaseDataSource.getEditingContext(); } public EOEntity getEntity() { return _entity; } public List<String> getEntityList() { if (_entityList == null) { _entityList = new ArrayList<String>(_wooModel.getModelGroup().getNonPrototypeEntityNames()); } return _entityList; } public String getEntityName() { return _entityName; } public int getEntriesPerBatch() { return _entriesPerBatch; } public boolean getFetchesOnLoad() { return _fetchesOnLoad; } public List<String> getFetchSpecList() { if (_entity != null) { try { Set<EOFetchSpecification> fetchSpecs = _entity.getSortedFetchSpecs(); if (fetchSpecs.size() > 0) { List<String> fetchSpecList = new ArrayList<String>(fetchSpecs.size() + 1); fetchSpecList.add(FETCH_SPEC_NONE); for (EOFetchSpecification fspec : fetchSpecs) { fetchSpecList.add(fspec.getName()); } return fetchSpecList; } } catch (Exception e) { e.printStackTrace(); } } return null; } public String getFetchSpecName() { String name = _databaseDataSource.getFetchSpecification().getName(); return name; } public List<String> getLocalKeys() { return _localKeys; } public EOEntity getMasterEntity() { return _masterEntity; } public String getMasterEntityName() { return _masterEntityName; } public String getName() { return _name; } public String getOriginalName() { return _originalName; } public int getQualificationIndex() { return _qualificationIndex; } public String[] getQualificationList() { return QUALIFICATION_LABELS.clone(); } public boolean getSelectsFirstObject() { return _selectsFirstObject; } public List<String> getSortList() { if (_entity != null) { Set<EOAttribute> attributes = _entity.getSortedClassAttributes(); List<String> attribList = new ArrayList<String>(attributes.size()); for (EOAttribute attribute : attributes) { attribList.add(attribute.getName()); } return attribList; } return new ArrayList<String>(); } public String getSortOrder() { String order = null; if (!_isSorted) { order = NOT_SORTED; } else { String selector = _sortOrder.getSelectorName(); if (selector.equals(EOSortOrdering.SELECTOR_ASCENDING)) { order = ASCENDING; } if (selector.equals(EOSortOrdering.SELECTOR_DESCENDING)) { order = DESCENDING; } } return order; } public String getSortOrderKey() { return _sortOrder.getKey(); } public WooModel getWooModel() { return _wooModel; } public boolean isHasMasterDetail() { return _hasMasterDetail; } @SuppressWarnings("unchecked") public void loadFromMap(final EOModelMap map, final Set<EOModelVerificationFailure> failures) { _originalName = _name; _className = map.getString("class", true); _localKeys = map.getList("localKeys"); if (map.containsKey("numberOfObjectsPerBatch")) { _entriesPerBatch = map.getInteger("numberOfObjectsPerBatch"); } if (map.containsKey("selectsFirstObjectAfterFetch")) { _selectsFirstObject = map.getBoolean("selectsFirstObjectAfterFetch"); } if (map.containsKey("fetchesOnLoad")) { _fetchesOnLoad = map.getBoolean("fetchesOnLoad"); } _qualifierFormat = map.getString("formatForLikeQualifier", true); List<String> qualificationFormatList = Arrays.asList(QUALIFICATION_FORMATS); _qualificationIndex = qualificationFormatList.indexOf(_qualifierFormat); if (map.containsKey("dataSource")) { EOModelMap dataSourceMap = new EOModelMap(map.getMap("dataSource")); try { EODataSource dataSource = EODataSourceFactory.createDataSourceFromMap(dataSourceMap, _wooModel.getModelGroup()); dataSource.loadFromMap(dataSourceMap, failures); _dataSource = dataSource; } catch (Throwable e) { e.printStackTrace(); } if (_dataSource instanceof EODetailDataSource) { EODetailDataSource ds = (EODetailDataSource) _dataSource; _hasMasterDetail = true; setMasterEntityName(ds.getMasterClass()); setDetailKeyName(ds.getDetailKey()); _detailDataSource = ds; } else if (_dataSource instanceof EODatabaseDataSource) { EODatabaseDataSource ds = (EODatabaseDataSource) _dataSource; _hasMasterDetail = false; setEntityName(ds.getEntityName()); _databaseDataSource = ds; } if (_entityName == null) { // XXX Invalid display group if (dataSourceMap.containsKey("fetchSpecification")) { EOModelMap fetchSpecMap = new EOModelMap(dataSourceMap.getMap("fetchSpecification")); _entityName = fetchSpecMap.getString("entityName", true); } else if (dataSourceMap.containsKey("masterClassDescription")) { _entityName = dataSourceMap.getString("masterClassDescription", true); } } } List<Map<Object, Object>> sortOrderList = map.getList("sortOrdering"); if (sortOrderList != null) { for (Map<Object, Object> sortOrdering : sortOrderList) { if (sortOrdering != null) { EOModelMap sortOrderingMap = new EOModelMap(sortOrdering); _sortOrder.loadFromMap(sortOrderingMap); _isSorted = true; } } } } public void removePropertyChangeListener(final PropertyChangeListener listener) { _changeSupport.removePropertyChangeListener(listener); } public void removePropertyChangeListener(final String name, final PropertyChangeListener listener) { _changeSupport.removePropertyChangeListener(name, listener); } public void setClassName(final String className) { String oldClass = getClassName(); String _name = className; if ((className == null || !getClassNameList().contains(className))) { _name = "WODisplayGroup"; } _className = _name; firePropertyChange(CLASS_NAME, oldClass, _name); setClassNameIndex(getClassNameList().indexOf(_name)); } public void setClassNameIndex(final int index) { int oldIndex = _classNameIndex; _classNameIndex = index; _className = _classNameList.get(index); firePropertyChange(CLASS_NAME_INDEX, oldIndex, _classNameIndex); } public void setDetailKeyName(final String key) { String oldDetailKeyName = _detailKeyName; _detailKeyName = key; if (key != null && isHasMasterDetail()) { EORelationship relation = _masterEntity.getRelationshipNamed(key); if (relation != null) { setEntity(relation.getDestination().getEntity()); } else { setEntity(_masterEntity); } } _detailDataSource.setDetailKey(_detailKeyName); firePropertyChange(DETAIL_KEY_NAME, oldDetailKeyName, _detailKeyName); } public void setEditingContext(final String ec) { String oldEditingContext = _databaseDataSource.getEditingContext(); _databaseDataSource.setEditingContext(ec); firePropertyChange(EDITING_CONTEXT, oldEditingContext, _databaseDataSource.getEditingContext()); } private void setEntity(final EOEntity entity) { if (entity == null || !entity.equals(_entity)) { List<String> oldFetchSpecList = getFetchSpecList(); List<String> oldSortList = getSortList(); _entity = entity; if (_entity != null) { setEntityName(_entity.getName()); } if (!isHasMasterDetail()) { setMasterEntity(entity); } _databaseDataSource.getFetchSpecification().setEntity(entity); firePropertyChange(FETCH_SPEC_LIST, oldFetchSpecList, getFetchSpecList()); setFetchSpecName(null); firePropertyChange(SORT_LIST, oldSortList, getSortList()); setSortOrderKey(null); } } public void setEntityName(final String entity) { String oldEntityName = _entityName; if (entity == null || !entity.equals(_entityName)) { _entityName = entity; firePropertyChange(ENTITY_NAME, oldEntityName, _entityName); try { EOEntity eoentity = _wooModel.getModelGroup().getEntityNamed(entity); setEntity(eoentity); } catch (Exception e) { e.printStackTrace(); setEntity(null); } } } public void setEntriesPerBatch(final int entriesPerBatch) { int oldEntriesPerBatch = _entriesPerBatch; _entriesPerBatch = entriesPerBatch; firePropertyChange(ENTRIES_PER_BATCH, oldEntriesPerBatch, _entriesPerBatch); } public void setFetchesOnLoad(final boolean fetchesOnLoad) { boolean oldFetchesOnLoad = _fetchesOnLoad; _fetchesOnLoad = fetchesOnLoad; firePropertyChange(FETCHES_ON_LOAD, oldFetchesOnLoad, _fetchesOnLoad); } public void setFetchSpecName(final String fetchSpec) { String _fetchSpec = fetchSpec; String oldFetchSpecName = getFetchSpecName(); EOFetchSpecification myFetchSpec = null; if (fetchSpec != null && _entity != null) { myFetchSpec = _entity.getFetchSpecNamed(fetchSpec); } if (myFetchSpec != null) { _databaseDataSource.setFetchSpecification(myFetchSpec); } else { EOFetchSpecification newFetchSpec = new EOFetchSpecification(null); newFetchSpec.setEntity(_entity); newFetchSpec.setDeep(true); _databaseDataSource.setFetchSpecification(newFetchSpec); } if (fetchSpec == null && getFetchSpecList() != null) { _fetchSpec = FETCH_SPEC_NONE; } firePropertyChange(FETCH_SPEC_NAME, oldFetchSpecName, _fetchSpec); } public void setHasMasterDetail(final boolean hasMasterDetail) { if (_hasMasterDetail == hasMasterDetail) { return; } boolean oldHasMasterDetail = _hasMasterDetail; _hasMasterDetail = hasMasterDetail; if (hasMasterDetail) { _dataSource = _detailDataSource; } else { _dataSource = _databaseDataSource; } firePropertyChange(HAS_MASTER_DETAIL, oldHasMasterDetail, _hasMasterDetail); } public void setLocalKeys(final List<String> localKeys) { // Unused _localKeys = localKeys; } private void setMasterEntity(final EOEntity entity) { List<String> oldDetailKeyList = getDetailKeyList(); if (entity == null || !entity.equals(_masterEntity)) { _masterEntity = entity; if (_masterEntity != null) { setMasterEntityName(_masterEntity.getName()); } if (isHasMasterDetail()) { setEntity(entity); } _detailDataSource.setMasterClass(_masterEntityName); firePropertyChange(DETAIL_KEY_LIST, oldDetailKeyList, getDetailKeyList()); } } public void setMasterEntityName(final String entity) { String oldMasterEntityName = _masterEntityName; if (entity == null || !entity.equals(_masterEntityName)) { _masterEntityName = entity; firePropertyChange(MASTER_ENTITY_NAME, oldMasterEntityName, _masterEntityName); try { EOEntity eoentity = _wooModel.getModelGroup().getEntityNamed(entity); setMasterEntity(eoentity); } catch (Exception e) { setMasterEntity(null); } } } public void setName(final String name) { String oldName = _name; _name = name; firePropertyChange(NAME, oldName, _name); } public void setQualificationIndex(final int qualification) { int oldQualificationIndex = _qualificationIndex; _qualificationIndex = qualification; _qualifierFormat = QUALIFICATION_FORMATS[_qualificationIndex]; firePropertyChange(QUALIFICATION_INDEX, oldQualificationIndex, _qualificationIndex); } public void setSelectsFirstObject(final boolean value) { boolean oldSelectsFirstObject = _selectsFirstObject; _selectsFirstObject = value; firePropertyChange(SELECTS_FIRST_OBJECT, oldSelectsFirstObject, _selectsFirstObject); } public void setSortOrder(final String order) { String oldSortOrder = getSortOrder(); if (order.equals(ASCENDING)) { _sortOrder.setSelectorName(EOSortOrdering.SELECTOR_ASCENDING); _isSorted = true; } if (order.equals(DESCENDING)) { _sortOrder.setSelectorName(EOSortOrdering.SELECTOR_DESCENDING); _isSorted = true; } if (order.equals(NOT_SORTED)) { _isSorted = false; } firePropertyChange(SORT_ORDER, oldSortOrder, getSortOrder()); } public void setSortOrderKey(final String key) { String oldSortOrderKey = getSortOrderKey(); String _key = key; if (key == null && getSortList().size() > 0) { _key = getSortList().get(0); } _sortOrder.setKey(_key); firePropertyChange(SORT_ORDER_KEY, oldSortOrderKey, _key); } public void setWooModel(final WooModel model) { _wooModel = model; } public EOModelMap toMap() { // XXX Need to validate model before saving if (_entity == null) { //return null; } EOModelMap modelMap = new EOModelMap(); modelMap.setString("class", _className, true); modelMap.setMap("dataSource", _dataSource.toMap(), true); modelMap.setBoolean("fetchesOnLoad", _fetchesOnLoad, EOModelMap.YESNO); modelMap.setString("formatForLikeQualifier", _qualifierFormat, true); modelMap.setList("localKeys", _localKeys, true); modelMap.setInteger("numberOfObjectsPerBatch", _entriesPerBatch); modelMap.setBoolean("selectsFirstObjectAfterFetch", _selectsFirstObject, EOModelMap.YESNO); if (_isSorted) { List<Object> sortOrderingList = new ArrayList<Object>(); sortOrderingList.add(_sortOrder.toMap()); modelMap.setList("sortOrdering", sortOrderingList, true); } _originalName = _name; return modelMap; } }