blob: b5780555f79d0745ffea2ed5de85daa76dbdf121 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2005 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*******************************************************************************/
package org.eclipse.wst.xml.ui.views.properties;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.IPropertySourceProvider;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManagerListener;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySource;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Configuration for property sheet page which shows XML content.
*
* @see org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration
* @since 1.0
*/
public class XMLPropertySheetConfiguration extends PropertySheetConfiguration {
private class CMDocumentManagerListenerImpl implements CMDocumentManagerListener {
public void cacheCleared(CMDocumentCache cache) {
// nothing to do
}
public void cacheUpdated(CMDocumentCache cache, final String uri, int oldStatus, int newStatus, CMDocument cmDocument) {
if (newStatus == CMDocumentCache.STATUS_LOADED || newStatus == CMDocumentCache.STATUS_ERROR) {
refreshPages();
}
}
public void propertyChanged(CMDocumentManager cmDocumentManager, String propertyName) {
if (cmDocumentManager.getPropertyEnabled(CMDocumentManager.PROPERTY_AUTO_LOAD)) {
refreshPages();
}
}
private void refreshPages() {
getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
getPropertiesRefreshJob().schedule(PropertiesRefreshJob.UPDATE_DELAY);
}
}
private class PropertiesRefreshJob extends UIJob {
public static final int UPDATE_DELAY = 200;
private Set propertySheetPages = null;
public PropertiesRefreshJob() {
super(XMLUIMessages.JFaceNodeAdapter_1);
setSystem(true);
setPriority(Job.SHORT);
propertySheetPages = new HashSet(1);
}
void addPropertySheetPage(IPropertySheetPage page) {
propertySheetPages.add(page);
schedule(UPDATE_DELAY);
}
public IStatus runInUIThread(IProgressMonitor monitor) {
Object[] pages = propertySheetPages.toArray();
propertySheetPages.clear();
for (int i = 0; i < pages.length; i++) {
PropertySheetPage page = (PropertySheetPage) pages[i];
if (page.getControl() != null && !page.getControl().isDisposed()) {
page.refresh();
}
}
return Status.OK_STATUS;
}
}
private class XMLPropertySheetRefreshAdapter implements INodeAdapter {
public boolean isAdapterForType(Object type) {
return false;
}
public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
if (fPropertySheetPage != null) {
getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
}
}
}
private class XMLPropertySourceProvider implements IPropertySourceProvider {
private IPropertySource fPropertySource = null;
private INodeNotifier fSource = null;
public IPropertySource getPropertySource(Object object) {
if (fSource != null && object.equals(fSource)) {
return fPropertySource;
}
if (object instanceof IDOMNode) {
fSource = (INodeNotifier) object;
fPropertySource = (IPropertySource) fSource.getAdapterFor(IPropertySource.class);
if (fPropertySource == null) {
fPropertySource = new XMLPropertySource((INodeNotifier) object);
}
}
else {
fSource = null;
fPropertySource = null;
}
return fPropertySource;
}
}
private CMDocumentManagerListenerImpl fCMDocumentManagerListener = new CMDocumentManagerListenerImpl();
private PropertiesRefreshJob fPropertiesRefreshJob = null;
IPropertySheetPage fPropertySheetPage = null;
private IPropertySourceProvider fPropertySourceProvider = null;
private INodeAdapter fRefreshAdapter = new XMLPropertySheetRefreshAdapter();
private CMDocumentManager[] fSelectedCMDocumentManagers = new CMDocumentManager[0];
private INodeNotifier[] fSelectedNotifiers = new INodeNotifier[0];
/**
* Create new instance of XMLPropertySheetConfiguration
*/
public XMLPropertySheetConfiguration() {
// Must have empty constructor to createExecutableExtension
super();
}
public ISelection getInputSelection(IWorkbenchPart selectingPart, ISelection selection) {
if (fSelectedNotifiers != null) {
for (int i = 0; i < fSelectedNotifiers.length; i++) {
fSelectedNotifiers[i].removeAdapter(fRefreshAdapter);
}
fSelectedNotifiers = null;
}
for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
}
ISelection preferredSelection = selection;
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSel = (IStructuredSelection) selection;
/*
* On Attr nodes, select the owner Element. On Text nodes, select
* the parent Element.
*/
Object[] selectedObjects = new Object[structuredSel.size()];
System.arraycopy(structuredSel.toArray(), 0, selectedObjects, 0, selectedObjects.length);
for (int i = 0; i < selectedObjects.length; i++) {
Object inode = selectedObjects[i];
if (inode instanceof Node) {
Node node = (Node) inode;
// replace Attribute Node with its owner
Node parentNode = node.getParentNode();
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
Element ownerElement = ((Attr) node).getOwnerElement();
selectedObjects[i] = ownerElement;
}
// replace Text Node with its parent
else if ((node.getNodeType() == Node.TEXT_NODE || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && parentNode != null) {
selectedObjects[i] = parentNode;
}
}
}
if (selectedObjects.length > 0) {
Set managers = new HashSet(1);
Set selectedNotifiers = new HashSet(1);
for (int i = 0; i < selectedObjects.length; i++) {
if (selectedObjects[i] instanceof Node) {
ModelQuery query = ModelQueryUtil.getModelQuery(((Node) selectedObjects[i]).getOwnerDocument());
if (query != null) {
CMDocumentManager mgr = query.getCMDocumentManager();
if (mgr != null) {
managers.add(mgr);
mgr.addListener(fCMDocumentManagerListener);
}
}
}
/*
* Add UI refresh adapters and remember notifiers for
* later removal
*/
if (selectedObjects[i] instanceof INodeNotifier) {
selectedNotifiers.add(selectedObjects[i]);
((INodeNotifier) selectedObjects[i]).addAdapter(fRefreshAdapter);
}
}
fSelectedCMDocumentManagers = (CMDocumentManager[]) managers.toArray(new CMDocumentManager[managers.size()]);
fSelectedNotifiers = (INodeNotifier[]) selectedNotifiers.toArray(new INodeNotifier[selectedNotifiers.size()]);
}
preferredSelection = new StructuredSelection(selectedObjects);
}
return preferredSelection;
}
PropertiesRefreshJob getPropertiesRefreshJob() {
if (fPropertiesRefreshJob == null) {
fPropertiesRefreshJob = new PropertiesRefreshJob();
}
return fPropertiesRefreshJob;
}
public IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page) {
if (fPropertySourceProvider == null) {
fPropertySheetPage = page;
fPropertySourceProvider = new XMLPropertySourceProvider();
}
return fPropertySourceProvider;
}
public void unconfigure() {
super.unconfigure();
for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
}
fPropertySheetPage = null;
}
}