/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.hibernate.eclipse.mapper.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.List; import org.eclipse.osgi.util.NLS; import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener; import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory; import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.hibernate.console.ConsoleConfiguration; import org.hibernate.eclipse.console.model.IRevEngColumn; import org.hibernate.eclipse.console.model.IRevEngGenerator; import org.hibernate.eclipse.console.model.IRevEngParameter; import org.hibernate.eclipse.console.model.IRevEngPrimaryKey; import org.hibernate.eclipse.console.model.IRevEngTable; import org.hibernate.eclipse.console.model.IReverseEngineeringDefinition; import org.hibernate.eclipse.console.model.ITableFilter; import org.hibernate.eclipse.console.model.ITypeMapping; import org.hibernate.eclipse.mapper.MapperMessages; import org.hibernate.eclipse.mapper.factory.ObserverAdapterFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; public class DOMReverseEngineeringDefinition implements IReverseEngineeringDefinition { private IModelStateListener listener = new IModelStateListener() { public void modelReinitialized(IStructuredModel structuredModel) { //System.out.println("reinit" + structuredModel); } public void modelAboutToBeReinitialized(IStructuredModel structuredModel) { //System.out.println("about to be reinit" + structuredModel); } public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) { //System.out.println("res moved" + oldModel); } public void modelResourceDeleted(IStructuredModel model) { //System.out.println("deleted" + model); } public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) { //System.out.println("dirty changed " + model + " to " + isDirty); } int cnt = 0; public void modelChanged(IStructuredModel model) { //System.out.println("model changed" + cnt++); //pcs.firePropertyChange(null, null, null); } public void modelAboutToBeChanged(IStructuredModel model) { //System.out.println("about to be changed" + cnt++); } }; private ObserverAdapterFactory factory; private IDOMDocument document; public DOMReverseEngineeringDefinition(IDOMDocument document) { this.document = document; factory = new ObserverAdapterFactory(this); document.getModel().addModelStateListener(listener); factory.adapt(document); } public ITableFilter createTableFilter(ConsoleConfiguration cc) { return (ITableFilter) factory.adapt((INodeNotifier) getDocument().createElement("table-filter")); //$NON-NLS-1$ } public void addTableFilter(ITableFilter filter) { if ( filter instanceof TableFilterAdapter ) { TableFilterAdapter tf = (TableFilterAdapter) filter; factory.adapt((INodeNotifier) tf.getNode()); List lastChild = DOMModelUtil.getChildrenByTagName(getDocument().getDocumentElement(),"table-filter"); //$NON-NLS-1$ if(lastChild==null || lastChild.isEmpty()) { List typeMapping = DOMModelUtil.getChildrenByTagName(getDocument().getDocumentElement(),"type-mapping"); //$NON-NLS-1$ if(typeMapping==null || typeMapping.isEmpty()) { List tableMapping = DOMModelUtil.getChildrenByTagName(getDocument().getDocumentElement(),"table"); //$NON-NLS-1$ if(tableMapping==null || tableMapping.isEmpty()) { getDocument().getDocumentElement().appendChild(tf.getNode()); } else { Element e = (Element) tableMapping.get(tableMapping.size()-1); getDocument().getDocumentElement().insertBefore(tf.getNode(),e); } } else { Element e = (Element) typeMapping.get(typeMapping.size()-1); getDocument().getDocumentElement().insertBefore(tf.getNode(), e.getNextSibling()); } } else { Element e = (Element) lastChild.get(lastChild.size()-1); getDocument().getDocumentElement().insertBefore(tf.getNode(), e.getNextSibling()); } DOMModelUtil.formatNode(tf.getNode().getParentNode()); } } PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener pcl) { pcs.addPropertyChangeListener(pcl); } public void removePropertyChangeListener(PropertyChangeListener pcl) { pcs.removePropertyChangeListener(pcl); } public void addPropertyChangeListener(String property, PropertyChangeListener pcl) { pcs.addPropertyChangeListener(property, pcl); } public void removePropertyChangeListener(String property, PropertyChangeListener pcl) { pcs.removePropertyChangeListener(property, pcl); } public ITableFilter[] getTableFilters() { return (ITableFilter[]) getTableFiltersList().toArray(new ITableFilter[0]); } public void removeAllTableFilters() { List list = getTableFiltersList(); for (java.util.Iterator it = list.iterator(); it.hasNext(); ) { ITableFilter filter = (ITableFilter)it.next(); removeTableFilter(filter); } } public void removeTableFilter(ITableFilter filter) { if ( filter instanceof TableFilterAdapter ) { TableFilterAdapter tf = (TableFilterAdapter) filter; Node parentNode = tf.getNode().getParentNode(); Node previousSibling = tf.getNode().getPreviousSibling(); if(DOMModelUtil.isWhiteSpace(previousSibling)) { parentNode.removeChild(previousSibling); } parentNode.removeChild(tf.getNode()); DOMModelUtil.formatNode(parentNode); } } public void moveTableFilterDown(ITableFilter item) { if ( item instanceof TableFilterAdapter ) { TableFilterAdapter tfe = (TableFilterAdapter) item; Node nextSibling = DOMModelUtil.getNextNamedSibling( tfe.getNode(), "table-filter" ); //$NON-NLS-1$ if(nextSibling!=null) { DOMModelUtil.addElementBefore(tfe.getNode().getParentNode(), nextSibling, tfe.getNode()); } pcs.firePropertyChange(TABLEFILTER_STRUCTURE,null, null); } } public void moveTableFilterUp(ITableFilter item) { if ( item instanceof TableFilterAdapter ) { TableFilterAdapter tfe = (TableFilterAdapter) item; Node sibling = DOMModelUtil.getPreviousNamedSibling( tfe.getNode(), "table-filter"); //$NON-NLS-1$ if(sibling!=null) { DOMModelUtil.addElementBefore(tfe.getNode().getParentNode(), tfe.getNode(), sibling); } pcs.firePropertyChange(TABLEFILTER_STRUCTURE,null, null); } } private List getTableFiltersList() { return DOMModelUtil.getAdaptedElements(getDocument().getDocumentElement(), "table-filter", factory); //$NON-NLS-1$ } public void unknownNotifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) { String out = NLS.bind(MapperMessages.DOMReverseEngineeringDefinition_unknown_change, notifier, INodeNotifier.EVENT_TYPE_STRINGS[eventType]); System.out.println(out); } public void hibernateMappingChanged() { pcs.firePropertyChange(TABLEFILTER_STRUCTURE,null,null); pcs.firePropertyChange(TYPEMAPPING_STRUCTURE,null,null); pcs.firePropertyChange(TABLES_STRUCTURE,null,null); } public void tableFilterChanged(INodeNotifier notifier) { pcs.firePropertyChange(TABLEFILTER_STRUCTURE,null,null); // could also be more specific but then need to map between node and TableFilter } public ITypeMapping[] getTypeMappings() { return (ITypeMapping[]) getTypeMappingsList().toArray(new ITypeMapping[0]); } private List getTypeMappingsList() { List result = new ArrayList(); List list = DOMModelUtil.getChildrenByTagName(getDocument().getDocumentElement(),"type-mapping"); //$NON-NLS-1$ for (int i = 0; i < list.size(); i++) { Element item = (Element) list.get(i); List sqllist = DOMModelUtil.getChildrenByTagName(item, "sql-type"); //$NON-NLS-1$ for (int j = 0; j < sqllist.size(); j++) { Element item2 = (Element) sqllist.get(j); result.add(factory.adapt((INodeNotifier) item2)); } } return result; } public ITypeMapping createTypeMapping() { return (ITypeMapping) factory.adapt((INodeNotifier)getDocument().createElement("sql-type")); //$NON-NLS-1$ } public void addTypeMapping(ITypeMapping typeMapping) { if ( typeMapping instanceof TypeMappingAdapter ) { TypeMappingAdapter tf = (TypeMappingAdapter) typeMapping; List parentList = DOMModelUtil.getChildrenByTagName(getDocument().getDocumentElement(),"type-mapping"); //$NON-NLS-1$ Element parent; if(parentList.isEmpty()) { parent = getDocument().createElement("type-mapping"); //$NON-NLS-1$ factory.adapt((INodeNotifier)parent); Node firstChild = getDocument().getDocumentElement().getFirstChild(); if(firstChild==null) { parent = (Element) getDocument().getDocumentElement().appendChild(parent); } else { parent = (Element) getDocument().getDocumentElement().insertBefore(parent, firstChild); } } else { parent = (Element) parentList.get(0); } parent.appendChild(tf.getNode()); DOMModelUtil.formatNode(tf.getNode().getParentNode()); } } public void typeMappingChanged(INodeNotifier notifier) { pcs.firePropertyChange(TYPEMAPPING_STRUCTURE, null,null); } public void sqlTypeChanged(INodeNotifier notifier) { pcs.firePropertyChange(TYPEMAPPING_STRUCTURE, null,null); } public void moveTypeMappingDown(ITypeMapping item) { if ( item instanceof TypeMappingAdapter ) { TypeMappingAdapter tfe = (TypeMappingAdapter) item; Node nextSibling = DOMModelUtil.getNextNamedSibling( tfe.getNode(), "sql-type" ); //$NON-NLS-1$ if(nextSibling!=null) { DOMModelUtil.addElementBefore(tfe.getNode().getParentNode(), nextSibling, tfe.getNode()); } } } public void moveTypeMappingUp(ITypeMapping item) { if ( item instanceof TypeMappingAdapter ) { TypeMappingAdapter tfe = (TypeMappingAdapter) item; Node sibling = DOMModelUtil.getPreviousNamedSibling( tfe.getNode(), "sql-type"); //$NON-NLS-1$ if(sibling!=null) { DOMModelUtil.addElementBefore(tfe.getNode().getParentNode(), tfe.getNode(), sibling); } } } public void removeAllTypeMappings() { List list = getTypeMappingsList(); for (java.util.Iterator it = list.iterator(); it.hasNext(); ) { ITypeMapping filter = (ITypeMapping)it.next(); removeTypeMapping(filter); } } public void removeTypeMapping(ITypeMapping item) { if ( item instanceof TypeMappingAdapter) { TypeMappingAdapter tf = (TypeMappingAdapter) item; Node parentNode = tf.getNode().getParentNode(); Node previousSibling = tf.getNode().getPreviousSibling(); if(DOMModelUtil.isWhiteSpace(previousSibling)) { parentNode.removeChild(previousSibling); } parentNode.removeChild(tf.getNode()); DOMModelUtil.formatNode(parentNode); if(parentNode.getChildNodes().getLength()==0) { Node parentNode2 = parentNode.getParentNode(); parentNode2.removeChild(parentNode); } } } public IRevEngTable[] getTables() { return (IRevEngTable[]) getTablesList().toArray(new IRevEngTable[0]); } private List getTablesList() { return DOMModelUtil.getAdaptedElements(getDocument().getDocumentElement(), "table",factory); //$NON-NLS-1$ } public void tablesChanged(INodeNotifier notifier) { pcs.firePropertyChange(TABLES_STRUCTURE, null,null); } public INodeAdapterFactory getNodeFactory() { return factory; } private Document getDocument() { return document; } public IRevEngTable createTable() { return (IRevEngTable) factory.adapt((INodeNotifier) getDocument().createElement("table")); //$NON-NLS-1$ } public void addTable(IRevEngTable retable) { if ( retable instanceof RevEngTableAdapter ) { RevEngTableAdapter tf = (RevEngTableAdapter) retable; getDocument().getDocumentElement().appendChild(tf.getNode()); DOMModelUtil.formatNode(tf.getNode().getParentNode()); } } public void removeTable(IRevEngTable retable) { removeDomAdapterNode(retable); } public void removeColumn(IRevEngColumn recolumn) { removeDomAdapterNode(recolumn); } public void removeGenerator(IRevEngGenerator regenerator) { removeDomAdapterNode(regenerator); } public void removeParameter(IRevEngParameter reparam) { removeDomAdapterNode(reparam); } public void removePrimaryKey(IRevEngPrimaryKey reprimaryKey) { removeDomAdapterNode(reprimaryKey); } private void removeDomAdapterNode(Object node){ if (node instanceof DOMAdapter) { DOMAdapter pf = (DOMAdapter) node; Node parentNode = pf.getNode().getParentNode(); Node previousSibling = pf.getNode().getPreviousSibling(); if (DOMModelUtil.isWhiteSpace(previousSibling)) { parentNode.removeChild(previousSibling); } parentNode.removeChild(pf.getNode()); DOMModelUtil.formatNode(parentNode); } } public IRevEngColumn createColumn() { return (IRevEngColumn) factory.adapt((INodeNotifier) getDocument().createElement("column")); //$NON-NLS-1$ } public IRevEngColumn createKeyColumn() { return (IRevEngColumn) factory.adapt((INodeNotifier) getDocument().createElement("key-column")); //$NON-NLS-1$ } public IRevEngPrimaryKey createPrimaryKey() { return (IRevEngPrimaryKey) factory.adapt((INodeNotifier) getDocument().createElement("primary-key")); //$NON-NLS-1$ } public IRevEngGenerator createGenerator() { return (IRevEngGenerator) factory.adapt((INodeNotifier) getDocument().createElement("generator")); //$NON-NLS-1$ } public IRevEngParameter createParameter() { return (IRevEngParameter) factory.adapt((INodeNotifier) getDocument().createElement("param")); //$NON-NLS-1$ } }