/*******************************************************************************
 * Copyright (c) 2010, 2015 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jaxb.ui.internal.properties;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.jface.window.Window;
import org.eclipse.jpt.common.ui.internal.WorkbenchTools;
import org.eclipse.jpt.common.ui.internal.swt.ColumnAdapter;
import org.eclipse.jpt.common.ui.internal.swt.TableModelAdapter;
import org.eclipse.jpt.common.ui.internal.swt.bindings.SWTBindingTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
import org.eclipse.jpt.common.utility.internal.iterable.SingleElementIterable;
import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
import org.eclipse.jpt.common.utility.internal.model.value.AspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.BufferedModifiablePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.CollectionPropertyValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.SimpleCollectionValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SortedListValueModelAdapter;
import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiableCollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.jaxb.core.JaxbProject;
import org.eclipse.jpt.jaxb.core.JaxbProjectManager;
import org.eclipse.jpt.jaxb.core.JaxbWorkspace;
import org.eclipse.jpt.jaxb.core.SchemaEntry;
import org.eclipse.jpt.jaxb.core.xsd.XsdUtil;
import org.eclipse.jpt.jaxb.ui.JaxbWorkbench;
import org.eclipse.jpt.jaxb.ui.JptJaxbUiMessages;
import org.eclipse.jpt.jaxb.ui.internal.wizards.classesgen.SelectFileOrXMLCatalogIdPanel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl;
import org.eclipse.xsd.XSDSchema;

/**
 * Shows the schemas associated with a JAXB project
 */
public class JaxbSchemasPropertiesPage
		extends PropertyPage {
	
	private static final int SIZING_SELECTION_PANE_WIDTH = 450;
	
	private final ResourceManager resourceManager;
	
	protected final ModifiablePropertyValueModel<IProject> projectModel;
	
	private final PropertyValueModel<JaxbProject> jaxbProjectModel;
	
	protected final BufferedModifiablePropertyValueModel.Trigger trigger;
	
	private final SchemasModel schemasModel;
	
	private final ModifiableCollectionValueModel<Schema> schemasSelectionModel;
	
	
	public JaxbSchemasPropertiesPage() {
		super();
		this.resourceManager = this.buildResourceManager();
		this.projectModel = new SimplePropertyValueModel<IProject>();
		this.jaxbProjectModel = new JaxbProjectModel(this.projectModel);
		this.trigger = new BufferedModifiablePropertyValueModel.Trigger();
		this.schemasModel = new SchemasModel(this.jaxbProjectModel, this.trigger);
		this.schemasSelectionModel = new SimpleCollectionValueModel<Schema>();
		setDescription(JptJaxbUiMessages.SCHEMAS_PAGE_DESCRIPTION);
	}
	
	private ResourceManager buildResourceManager() {
		return new LocalResourceManager(this.getParentResourceManager());
	}

	private ResourceManager getParentResourceManager() {
		return JFaceResources.getResources();
	}

	protected IProject getProject() {
		return this.projectModel.getValue();
	}
	
	@Override
	public final void createControl(Composite parent ) {
		super.createControl( parent );
		
		Button revertButton = getDefaultsButton();
		
		revertButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_REVERT);
		
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		Point minButtonSize = revertButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
		gd.widthHint = Math.max(convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH), minButtonSize.x);
		revertButton.setLayoutData(gd);
		
		updateButtons();
		
		getShell().layout(true, true);
    }
	
	@Override
	protected final Control createContents(Composite parent) {
		IAdaptable element = getElement();
		
		IProject project = null;
		if (element instanceof IProject) {
			project = (IProject) element;
		}
		else {
			project = (IProject) Platform.getAdapterManager().loadAdapter(element, IProject.class.getName());
		}
		
		this.projectModel.setValue(project);
		
		Composite pageComponent = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		pageComponent.setLayout(layout);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.widthHint = SIZING_SELECTION_PANE_WIDTH;
		pageComponent.setLayoutData(data);
		
		Label schemasLabel = new Label(pageComponent, SWT.LEFT);
		schemasLabel.setText(JptJaxbUiMessages.SCHEMAS_PAGE_SCHEMAS);
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.horizontalSpan = 2;
		schemasLabel.setLayoutData(data);
		
		// create the table composite
		Composite tableComposite = new Composite(pageComponent, SWT.NONE);
		data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.grabExcessHorizontalSpace = true;
		data.grabExcessVerticalSpace = true;
		data.widthHint = SIZING_SELECTION_PANE_WIDTH;
		tableComposite.setLayoutData(data);
		
		// create the table
		TableViewer schemasTable = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
		TableModelAdapter.adapt(
				new SortedListValueModelAdapter<Schema>(this.schemasModel),
				this.schemasSelectionModel,
				schemasTable.getTable(),
				new SchemaColumnAdapter(),
				new SchemaTableLabelProvider());
		ColumnViewerToolTipSupport.enableFor(schemasTable, ToolTip.NO_RECREATE);
		schemasTable.getTable().setHeaderVisible(true);
		schemasTable.getTable().setToolTipText(null);
        
		// set the table composite layout (after the table, so that column information is available)
		TableColumnLayout tableLayout = new TableColumnLayout();
		tableLayout.setColumnData(schemasTable.getTable().getColumn(0), new ColumnWeightData(15));
		tableLayout.setColumnData(schemasTable.getTable().getColumn(1), new ColumnWeightData(25));
		tableComposite.setLayout(tableLayout);
		
		// set the table layout data
		data = new GridData(GridData.FILL_BOTH);
		data.heightHint = schemasTable.getTable().getItemHeight() * 7;
		data.widthHint = 200;
		schemasTable.getTable().setLayoutData(data);
		
		createButtonGroup(pageComponent);
        
        Dialog.applyDialogFont(parent);
		
        return pageComponent;
    }
	
	protected void createButtonGroup(Composite parent) {
		Composite groupComponent = new Composite(parent, SWT.NULL);
		GridLayout groupLayout = new GridLayout();
		groupLayout.marginWidth = 0;
		groupLayout.marginHeight = 0;
		groupComponent.setLayout(groupLayout);
		GridData data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		groupComponent.setLayoutData(data);
		
		Button addButton = new Button(groupComponent, SWT.PUSH);
		addButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_ADD_BUTTON_LABEL);
		addButton.addSelectionListener(
				new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						addSchema();
					}
				});
		setButtonLayoutData(addButton);
		
		Button editButton = new Button(groupComponent, SWT.PUSH);
		editButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_BUTTON_LABEL);
		editButton.addSelectionListener(
				new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						editSelectedSchema();
					}
				});
		SWTBindingTools.bindEnabledState(buildEditEnabledModel(), editButton);
		setButtonLayoutData(editButton);
		
		Button removeButton = new Button(groupComponent, SWT.PUSH);
		removeButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_REMOVE_BUTTON_LABEL);
		removeButton.addSelectionListener(
				new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						removeSelectedSchemas();
					}
				});
		SWTBindingTools.bindEnabledState(buildRemoveEnabledModel(), removeButton);
        setButtonLayoutData(removeButton);
	}
	
	
	private void addSchema() {
		// constructs a dialog for editing the new schema namespace and location
		AddEditSchemaDialog dialog = 
				new AddEditSchemaDialog(
						getShell(),
						null,
						this.schemasModel.getAspectValue(),
						this.resourceManager);
		
		// opens the dialog - just returns if the user cancels it
		if (dialog.open() == Window.CANCEL) {
			return;
		}
		
		// otherwise, adds the new schema
		Schema schema = this.schemasModel.addSchema(dialog.getNamespace(), dialog.getLocation());
		
        // select the new schema
        this.schemasSelectionModel.setValues(new SingleElementIterable<Schema>(schema));
	}
	
	private PropertyValueModel<Boolean> buildEditEnabledModel() {
		return new CollectionPropertyValueModelAdapter<Boolean, Schema>(this.schemasSelectionModel) {
			@Override
			protected Boolean buildValue() {
				return Boolean.valueOf(this.collectionModel.size() == 1);
			}
		};
	}
	
	private void editSelectedSchema() {
		// constructs a dialog for editing the new schema namespace and location
		final Schema schema = this.schemasSelectionModel.iterator().next();
		AddEditSchemaDialog dialog = 
				new AddEditSchemaDialog(
						getShell(),
						schema,
						this.schemasModel.getAspectValue(),
						this.resourceManager);
		
		// opens the dialog - just returns if the user cancels it
		if (dialog.open() == Window.CANCEL) {
			return;
		}
		
		// otherwise, changes the new schema
		schema.setNamespace(dialog.getNamespace());
		schema.setLocation(dialog.getLocation());
	}
	
	private PropertyValueModel<Boolean> buildRemoveEnabledModel() {
		return new CollectionPropertyValueModelAdapter<Boolean, Schema>(this.schemasSelectionModel) {
			@Override
			protected Boolean buildValue() {
				return Boolean.valueOf(this.collectionModel.size() >= 1);
			}
		};
	}
	
	private void removeSelectedSchemas() {
		this.schemasModel.removeSchemas(this.schemasSelectionModel);
	}
	
	private void updateButtons() {
		boolean enableApply = isValid();
		boolean enableRevert = true;
		
		Button applyButton = getApplyButton();
		
		if (applyButton != null) {
			applyButton.setEnabled(enableApply);
		}
		
		Button revertButton = getDefaultsButton();
		
		if (revertButton != null) {
			revertButton.setEnabled(enableRevert);
		}
	}
	
	
	// ********** OK/Revert/Apply behavior **********

	@Override
	public boolean performOk() {
		try {
			// true=fork; false=uncancellable
			this.buildOkProgressMonitorDialog().run(true, false, this.buildOkRunnableWithProgress());
		}
		catch (InterruptedException ex) {
			// should *not* happen...
			Thread.currentThread().interrupt();
			return false;
		} 
		catch (InvocationTargetException ex) {
			throw new RuntimeException(ex.getTargetException());
		}

		return true;
	}

	private IRunnableContext buildOkProgressMonitorDialog() {
		return new ProgressMonitorDialog(this.getShell());
	}

	private IRunnableWithProgress buildOkRunnableWithProgress() {
		return new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				IWorkspace ws = ResourcesPlugin.getWorkspace();
				try {
					// the build we execute in #performOk_() locks the workspace root,
					// so we need to use the workspace root as our scheduling rule here
					ws.run(
							buildOkWorkspaceRunnable(),
							ws.getRoot(),
							IWorkspace.AVOID_UPDATE,
							monitor);
				}
				catch (CoreException ex) {
					throw new InvocationTargetException(ex);
				}
			}
		};
	}
	
	/* private */ IWorkspaceRunnable buildOkWorkspaceRunnable() {
		return new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				performOk_(monitor);
			}
		};
	}
	
	void performOk_(IProgressMonitor monitor) throws CoreException {
		if (this.schemasModel.hasChanges()) {
			this.trigger.accept();
			JaxbProjectManager jaxbProjectManager = this.getJaxbProjectManager();
			if (jaxbProjectManager != null) {
				jaxbProjectManager.rebuildJaxbProject(getProject());
			}
			getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
		}
	}

	private JaxbProjectManager getJaxbProjectManager() {
		JaxbWorkspace jaxbWorkspace = this.getJaxbWorkspace();
		return (jaxbWorkspace == null) ? null : jaxbWorkspace.getJaxbProjectManager();
	}

	private JaxbWorkspace getJaxbWorkspace() {
		JaxbWorkbench jaxbWorkbench = this.getJaxbWorkbench();
		return (jaxbWorkbench == null) ? null : jaxbWorkbench.getJaxbWorkspace();
	}

	private JaxbWorkbench getJaxbWorkbench() {
		return WorkbenchTools.getAdapter(JaxbWorkbench.class);
	}
	
	@Override
	protected void performDefaults() {
		this.trigger.reset();
	}
	
	@Override
	public void dispose() {
		this.resourceManager.dispose();
		super.dispose();
	}
	
	
	static class SchemasModel
			extends AspectAdapter<JaxbProject, Collection<Schema>>
			implements CollectionValueModel<Schema> {
		
		/**
		 * The collection of schemas
		 */
		protected final Collection<Schema> schemas;
		
		/**
		 * This is the trigger that indicates whether the buffered value
		 * should be accepted or reset.
		 */
		protected final PropertyValueModel<Boolean> triggerHolder;
	
		/** This listens to the trigger holder. */
		protected final PropertyChangeListener triggerChangeListener;

		
		SchemasModel(PropertyValueModel<JaxbProject> subjectHolder, PropertyValueModel<Boolean> triggerHolder) {
			super(subjectHolder);
			this.schemas = new ArrayList<Schema>();
			this.triggerHolder = triggerHolder;
			this.triggerChangeListener = buildTriggerChangeListener();
		}
		
		
		protected PropertyChangeListener buildTriggerChangeListener() {
			return new PropertyChangeListener() {
				public void propertyChanged(PropertyChangeEvent event) {
					triggerChanged(event);
				}
			};
		}
		
		protected Collection<Schema> buildSchemas_() {
			ArrayList<Schema> schemas = new ArrayList<Schema>();
			for (SchemaEntry entry : this.subject.getSchemaLibrary().getSchemaEntries()) {
				schemas.add(new Schema(entry.getNamespace(), entry.getLocation()));
			}
			return schemas;
		}
		
		public boolean hasChanges() {
			return (this.subject == null) ? false : ! this.schemas.equals(buildSchemas_());
		}
		
		protected void triggerChanged(PropertyChangeEvent event) {
			if (hasChanges()) {
				if (this.subject != null && ((Boolean) event.getNewValue()).booleanValue()) {
					this.accept();
				} else {
					this.reset();
				}
			}
		}
		
		public void accept() {
			List<String> schemaLocations = new Vector<String>();
			for (Schema schema : this.schemas) {
				schemaLocations.add(schema.getLocation());
			}
			this.subject.getSchemaLibrary().setSchemaLocations(schemaLocations);
		}
		
		public void reset() {
			this.schemas.clear();
			if (this.subject != null) {
				this.schemas.addAll(buildSchemas_());
			}
			fireCollectionChanged(VALUES, getAspectValue());
		}
		
		public Schema addSchema(String namespace, String location) {
			Schema schema = new Schema(namespace, location);
			addItemToCollection(schema, this.schemas, VALUES);
			return schema;
		}
		
		public void removeSchemas(Iterable<Schema> schemas) {
			removeItemsFromCollection(schemas, this.schemas, VALUES);
		}
		
		
		// ************ AspectAdapter impl ************************************
		
		@Override
		protected String getListenerAspectName() {
			return VALUES;
		}
		
		@Override
		protected Class<? extends EventListener> getListenerClass() {
			return CollectionChangeListener.class;
		}
		
		@Override
		protected boolean hasListeners() {
			return hasAnyCollectionChangeListeners(VALUES);
		}
		
		@Override
		protected void fireAspectChanged(Collection<Schema> oldValue, Collection<Schema> newValue) {
			this.synchronizeCollection(newValue, new ArrayList<Schema>(oldValue), VALUES);
		}
		
		@Override
		protected void engageSubject_() {
			this.schemas.addAll(buildSchemas_());
		}
		
		@Override
		protected void disengageSubject_() {
			this.schemas.clear();
		}
		
		@Override
		protected void engageModels() {
			super.engageModels();
			this.triggerHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.triggerChangeListener);
		}
		
		@Override
		protected void disengageModels() {
			this.triggerHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.triggerChangeListener);
			super.disengageModels();
		}
		
		@Override
		protected Collection<Schema> getAspectValue() {
			return CollectionTools.hashBag(iterator());
		}
		
		
		// ************ CollectionValueModel impl *****************************
		
		public Iterator<Schema> iterator() {
			return this.schemas.iterator();
		}
		
		public int size() {
			return this.schemas.size();
		}
	}
	
	
	static class Schema 
			extends AbstractModel
			implements Comparable<Schema> {
		
		static String locationDisplayString(String location) {
			if (location == null) {
				return StringTools.EMPTY_STRING;
			}
			
			URI uri = URI.createURI(location);
			if (uri.isPlatformResource()) {
				return uri.toPlatformString(false);
			}
			
			return location;
		}
		
		static String namespaceDisplayString(String namespace) {
			if (null == namespace || StringTools.EMPTY_STRING.equals(namespace)) {
				return JptJaxbUiMessages.SCHEMAS_PAGE_NO_NAMESPACE_TEXT;
			}
			
			return namespace;
		}
		
		Schema(String namespace, String location) {
			super();
			this.namespace = namespace;
			this.location = location;
		}
		
		
		private String namespace;
		final static String NAMESPACE_PROPERTY = "namespace"; //$NON-NLS-1$
		
		private String location;
		final static String LOCATION_PROPERTY = "location"; //$NON-NLS-1$
		
		
		String getNamespace() {
			return this.namespace;
		}
		
		void setNamespace(String namespace) {
			String old = this.namespace;
			this.namespace = namespace;
			firePropertyChanged(NAMESPACE_PROPERTY, old, namespace);
		}
		
		String namespaceDisplayString() {
			return namespaceDisplayString(this.namespace);
		}
		
		String getLocation() {
			return this.location;
		}
		
		String locationDisplayString() {
			return locationDisplayString(getLocation());
		}
		
		void setLocation(String location) {
			String old = this.location;
			this.location = location;
			firePropertyChanged(LOCATION_PROPERTY, old, location);
		}
		
		public int compareTo(Schema o) {
			return this.namespaceDisplayString().compareTo(o.namespaceDisplayString());
		}
	}
	
	
	static class SchemaColumnAdapter
			implements ColumnAdapter<Schema> {
		
		static final int COLUMN_COUNT = 2;
		static final int NAMESPACE_COLUMN = 0;
		static final int LOCATION_COLUMN = 1;
		
		
		public int columnCount() {
			return COLUMN_COUNT;
		}
		
		public String columnName(int columnIndex) {
			switch (columnIndex) {
				case NAMESPACE_COLUMN :
					return JptJaxbUiMessages.SCHEMAS_PAGE_NAMESPACE_COLUMN_LABEL;
				case LOCATION_COLUMN :
					return JptJaxbUiMessages.SCHEMAS_PAGE_LOCATION_COLUMN_LABEL;
				default :
					return null;
			}
		}
		
		public ModifiablePropertyValueModel<?>[] cellModels(Schema subject) {
			ModifiablePropertyValueModel<?>[] cellModels = new ModifiablePropertyValueModel<?>[COLUMN_COUNT];
			cellModels[NAMESPACE_COLUMN] = buildNamespaceCellModel(subject);
			cellModels[LOCATION_COLUMN] = buildLocationCellModel(subject);
			return cellModels;
		}
		
		private ModifiablePropertyValueModel<String> buildNamespaceCellModel(Schema subject) {
			return new PropertyAspectAdapter<Schema, String>(Schema.NAMESPACE_PROPERTY, subject) {
				@Override
				protected String buildValue_() {
					return this.subject.getNamespace();
				}
			};
		}
		
		private ModifiablePropertyValueModel<String> buildLocationCellModel(Schema subject) {
			return new PropertyAspectAdapter<Schema, String>(Schema.LOCATION_PROPERTY, subject) {
				@Override
				protected String buildValue_() {
					return this.subject.getLocation();
				}
			};
		}
	}
	
	
	static class SchemaTableLabelProvider
			extends LabelProvider
			implements ITableLabelProvider {
		
		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}
		
		public String getColumnText(Object element, int columnIndex) {
			switch (columnIndex) {
				case SchemaColumnAdapter.NAMESPACE_COLUMN :
					return ((Schema) element).namespaceDisplayString();
				case SchemaColumnAdapter.LOCATION_COLUMN :
					return ((Schema) element).locationDisplayString();
				default :
					return null;
			}
		}
	}
	
	
	static class AddEditSchemaDialog
			extends TitleAreaDialog {
		
		private final ResourceManager resourceManager;
		
		private final Schema currentSchema;
		
		private String defaultMessage;
		
		private final ModifiablePropertyValueModel<String> location;
		
		private final ModifiablePropertyValueModel<String> namespace;
		
		private XSDSchema resolvedSchema;
		
		private final Mode mode;
		
		private final Iterable<Schema> allSchemas;
		
		
		public AddEditSchemaDialog(Shell shell, Schema currentSchema, Iterable<Schema> allSchemas, ResourceManager resourceManager) {
			super(shell);
			this.resourceManager = resourceManager;
			this.currentSchema = currentSchema;
			this.allSchemas = allSchemas;
			this.location = new SimplePropertyValueModel<String>();
			this.namespace = new SimplePropertyValueModel<String>();
			
			this.mode = (this.currentSchema == null) ? Mode.ADD : Mode.EDIT;
			if (this.mode == Mode.ADD) {
				this.defaultMessage = JptJaxbUiMessages.SCHEMAS_PAGE_ADD_SCHEMA_MESSAGE;
				this.location.setValue(null);
				this.namespace.setValue(null);
			}
			else {
				this.defaultMessage = JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_SCHEMA_MESSAGE;
				this.location.setValue(currentSchema.getLocation());
				this.namespace.setValue(currentSchema.getNamespace());
			}
		}
		
		
		@Override
		protected void configureShell(Shell newShell) {
			super.configureShell(newShell);
			if (this.mode == Mode.ADD) {
				newShell.setText(JptJaxbUiMessages.SCHEMAS_PAGE_ADD_SCHEMA_DIALOG_TITLE);
			}
			else {
				newShell.setText(JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_SCHEMA_DIALOG_TITLE);
			}
		}
		
		@Override
		protected Control createDialogArea(Composite parent) {
			Composite dialogArea = (Composite) super.createDialogArea(parent);
			
			setMessage(this.defaultMessage);
			if (this.mode == Mode.ADD) {
				setTitle(JptJaxbUiMessages.SCHEMAS_PAGE_ADD_SCHEMA_TITLE);
			}
			else {
				setTitle(JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_SCHEMA_TITLE);
			}
			
			Composite composite = new Composite(dialogArea, SWT.NONE);
			composite.setLayout(new GridLayout(3, false));
			composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			
			Label locationLabel = new Label(composite, SWT.NULL);
			locationLabel.setText(JptJaxbUiMessages.SCHEMAS_PAGE_LOCATION_LABEL);
			locationLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
			
			final Text locationText = new Text(composite, SWT.SINGLE | SWT.BORDER);
			locationText.setText(locationDisplayString());
			locationText.setEditable(false);
			locationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
			this.location.addPropertyChangeListener(
					PropertyValueModel.VALUE,
					new PropertyChangeListener() {
						public void propertyChanged(PropertyChangeEvent event) {
							locationText.setText(locationDisplayString());
						}
					});
			
			Button browseButton = new Button(composite, SWT.PUSH);
			browseButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_BROWSE_BUTTON_LABEL);
			browseButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, true, 1, 1));
			browseButton.addSelectionListener(
					new SelectionListener() {
						public void widgetSelected(SelectionEvent e) {
							browseForSchemaLocation();
						}
						
						public void widgetDefaultSelected(SelectionEvent e) {
							widgetSelected(e);
						}
					});
			
			Label namespaceLabel = new Label(composite, SWT.NULL);
			namespaceLabel.setText(JptJaxbUiMessages.SCHEMAS_PAGE_NAMESPACE_LABEL);
			namespaceLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
			
			final Text namespaceText = new Text(composite, SWT.SINGLE | SWT.BORDER);
			namespaceText.setText(namespaceDisplayString());
			namespaceText.setEditable(false);
			namespaceText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
			this.namespace.addPropertyChangeListener(
					PropertyValueModel.VALUE,
					new PropertyChangeListener() {
						public void propertyChanged(PropertyChangeEvent event) {
							namespaceText.setText(namespaceDisplayString());
						}
					});
			
			Dialog.applyDialogFont(dialogArea);
			
			return dialogArea;
		}
		
		@Override
		public void create() {
			super.create();
			
			// disable ok button until user does something and then validation takes over
			getButton(IDialogConstants.OK_ID).setEnabled(false);
		}
		
		@Override
		protected boolean isResizable() {
			return true;
		}
		
		private void browseForSchemaLocation() {
			SchemaLocationDialog dialog = new SchemaLocationDialog(getShell(), this.resourceManager);
			
			// opens the dialog - just returns if the user cancels it
			if (dialog.open() == Window.CANCEL) {
				return;
			}
			
			String location = dialog.getLocation();
			this.location.setValue(location);
			
			String resolvedUri = XsdUtil.getResolvedUri(location);
			
			XSDSchema schema = XSDImpl.buildXSDModel(resolvedUri);
			String newNamespace = 
					(schema == null) ? 
							null 
							: ((schema.getTargetNamespace()) == null ? 
									StringTools.EMPTY_STRING
									: schema.getTargetNamespace());
			this.namespace.setValue(newNamespace);
			this.resolvedSchema = schema;
			
			validate();
		}
		
		public String getNamespace() {
			return this.namespace.getValue();
		}
		
		protected String namespaceDisplayString() {
			return Schema.namespaceDisplayString(getNamespace());
		}
		
		public String getLocation() {
			return this.location.getValue();
		}
		
		protected String locationDisplayString() {
			return Schema.locationDisplayString(getLocation());
		}
		
		private void validate() {
			if (this.resolvedSchema == null) {
				setErrorMessage(JptJaxbUiMessages.SCHEMAS_PAGE_SCHEMA_UNRESOLVED_MESSAGE);
			}
			else if (isDuplicateNamespace()) {
				setErrorMessage(JptJaxbUiMessages.SCHEMAS_PAGE_DUPLICATE_NAMESPACE_MESSAGE);
			}
			else if (StringTools.isBlank(this.location.getValue())) {
				setErrorMessage(JptJaxbUiMessages.SCHEMAS_PAGE_NO_LOCATION_MESSAGE);
			}
			else {
				setErrorMessage(null);
				setMessage(this.defaultMessage);
			}
			getButton(IDialogConstants.OK_ID).setEnabled(getErrorMessage() == null);
		}
		
		private boolean isDuplicateNamespace() {
			for (Schema schema : this.allSchemas) {
				if ((this.currentSchema != schema) && getNamespace().equals(schema.getNamespace())) {
					return true;
				}
			}
			return false;
		}
		
		
		private enum Mode {
			ADD,
			EDIT
		}
	}
	
	
	static class SchemaLocationDialog
			extends TrayDialog {
		
		private final ResourceManager resourceManager;

		private SelectFileOrXMLCatalogIdPanel locationPanel;
		
		private String location;
		
		
		public SchemaLocationDialog(Shell shell, ResourceManager resourceManager) {
			super(shell);
			this.resourceManager = resourceManager;
		}
		
		
		@Override
		protected void configureShell(Shell newShell) {
			super.configureShell(newShell);
			newShell.setText(JptJaxbUiMessages.SCHEMAS_PAGE_CHOOSE_LOCATION_TITLE);
		}
		
		@Override
		protected Control createDialogArea(Composite parent) {
			Composite composite = (Composite) super.createDialogArea(parent);
			
			this.locationPanel = new SelectFileOrXMLCatalogIdPanel(composite, StructuredSelection.EMPTY, this.resourceManager);
			this.locationPanel.setFilterExtensions(new String[] {".xsd"}); //$NON-NLS-1$
			this.locationPanel.update();
			this.locationPanel.setVisibleHelper(true);
			
			return composite;
		}
		
		@Override
		protected boolean isResizable() {
			return true;
		}
		
		@Override
		protected void okPressed() {
			IFile file = this.locationPanel.getFile();
			if (file != null) {
				this.location = URI.createPlatformResourceURI(file.getFullPath().toString(), false).toString();
			}
			else {
				this.location = this.locationPanel.getXMLCatalogId();
			}
			
			super.okPressed();
		}
		
		public String getLocation() {
			return this.location;
		}
	}
}
