/*
* 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$
}
}