/******************************************************************************* * Copyright (c) 2008 Olivier Moises * * 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: * Olivier Moises- initial API and implementation *******************************************************************************/ package org.eclipse.wazaabi.ui.runtime.parts; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.wazaabi.engine.edp.Registry; import org.eclipse.wazaabi.engine.edp.adapters.PropertyChangedEventAdapter; import org.eclipse.wazaabi.engine.edp.coderesolution.AbstractCodeDescriptor; import org.eclipse.wazaabi.engine.edp.impl.EDPRegistryImpl; import org.eclipse.wazaabi.engine.swt.viewers.SWTControlViewer; import org.eclipse.wazaabi.mm.core.widgets.AbstractComponent; import org.eclipse.wazaabi.mm.core.widgets.Container; import org.eclipse.wazaabi.mm.core.widgets.CoreWidgetsFactory; import org.eclipse.wazaabi.mm.edp.events.Event; import org.eclipse.wazaabi.mm.edp.events.PropertyChangedEvent; import org.eclipse.wazaabi.ui.model.parts.Page; public class WazaabiForm { public static final Container BLANK_CONTAINER = CoreWidgetsFactory.eINSTANCE .createContainer(); private AbstractCodeDescriptor.MethodDescriptor getObjectMethodDescriptor = null; private AbstractCodeDescriptor.MethodDescriptor getUiIdMethodDescriptor = null; private AbstractCodeDescriptor.MethodDescriptor getUiMethodDescriptor = null; private AbstractCodeDescriptor.MethodDescriptor getUiURIMethodDescriptor = null; private Page modelPage = null; private AbstractCodeDescriptor selectionProcessorCodeDescriptor = null; private HashMap<Object, AbstractComponent> uiIdToUiRegistry = new HashMap<Object, AbstractComponent>(); private AbstractCodeDescriptor uiSelectorCodeDescriptor = null; private URI uri; private SWTControlViewer viewer = null; private ResourceSet resourceSet = null; public WazaabiForm(String uri) { this(URI.createURI(uri)); } public WazaabiForm(URI uri) { this.uri = uri; // TODO : test uri != null } public WazaabiForm(Page modelPage) { this.modelPage = modelPage; } public void createControl(Composite parent) { createViewer(parent); if (modelPage == null) initializeModelPage(); initializeViewer(); } protected void createViewer(Composite parent) { setViewer(new SWTControlViewer(parent)); } protected void initializeViewer() { getViewer().setContents(getModelPage()); } protected void initializeModelPage() { if (getUri() != null) { Resource resource = null; try { resource = new ResourceSetImpl().getResource(getUri(), true); //$NON-NLS-1$ } catch (Throwable t) { // TODO : log this t.printStackTrace(); } if (resource != null && !resource.getContents().isEmpty() && resource.getContents().get(0) instanceof Page) { setModelPage((Page) resource.getContents().get(0)); initializeCodeDescriptors((Page) resource.getContents().get(0)); } }// else log : no propertypage found } protected void initializeCodeDescriptors(Page page) { if (page != null) { Registry registry = new EDPRegistryImpl(); // TODO move from this location selectionProcessorCodeDescriptor = (AbstractCodeDescriptor) registry .createComponent(this, page.getSelectionProcessor(), null, AbstractCodeDescriptor.class); registerSelectionProcessorMethods(getSelectionProcessorCodeDescriptor()); uiSelectorCodeDescriptor = (AbstractCodeDescriptor) registry .createComponent(this, page.getUiSelector(), null, AbstractCodeDescriptor.class); registerUIselectorMethods(getUiSelectorCodeDescriptor()); } } public void dispose() { releaseCodeDescriptor(getSelectionProcessorCodeDescriptor()); releaseCodeDescriptor(getUiSelectorCodeDescriptor()); Control ctrl = getControl(); if (ctrl != null && !ctrl.isDisposed()) { ctrl.dispose(); } } protected List<PropertyChangedEventAdapter> getAllRelatedPropertyChangedEventAdapters( EObject root, String contextEntry) { List<PropertyChangedEventAdapter> result = new ArrayList<PropertyChangedEventAdapter>(); TreeIterator<EObject> i = EcoreUtil.getAllContents(root, true); while (i.hasNext()) { EObject item = i.next(); if (item instanceof PropertyChangedEvent && ((PropertyChangedEvent) item).getPath() != null && ((PropertyChangedEvent) item).getPath().startsWith( "$" + contextEntry)) for (Adapter adapter : ((PropertyChangedEvent) item) .eAdapters()) if (adapter instanceof PropertyChangedEventAdapter && !result.contains(adapter)) result.add((PropertyChangedEventAdapter) adapter); } return result; } public Control getControl() { return getViewer().getControl(); } protected AbstractCodeDescriptor.MethodDescriptor getGetObjectMethodDescriptor() { return getObjectMethodDescriptor; } protected AbstractCodeDescriptor.MethodDescriptor getGetUiIdMethodDescriptor() { return getUiIdMethodDescriptor; } protected AbstractCodeDescriptor.MethodDescriptor getGetUiMethodDescriptor() { return getUiMethodDescriptor; } protected AbstractCodeDescriptor.MethodDescriptor getGetUiURIMethodDescriptor() { return getUiURIMethodDescriptor; } protected AbstractCodeDescriptor.MethodDescriptor getReleaseMethodDescriptor( AbstractCodeDescriptor codeDescriptor) { if (codeDescriptor != null) return codeDescriptor.getMethodDescriptor( "dispose", null, null, null); //$NON-NLS-1$ return null; } protected AbstractCodeDescriptor getSelectionProcessorCodeDescriptor() { return selectionProcessorCodeDescriptor; } protected AbstractComponent getUi(Object input) { if (input != null) { if (getUiSelectorCodeDescriptor() != null && getGetUiIdMethodDescriptor() != null) return resolveUI( input, getUiSelectorCodeDescriptor().invokeMethod( getGetUiIdMethodDescriptor(), new Object[] { input })); return resolveUI(input, input.getClass()); } return null; } protected AbstractCodeDescriptor getUiSelectorCodeDescriptor() { return uiSelectorCodeDescriptor; } public URI getUri() { return uri; } protected String getURIFromConfiguration(Object uiId) { // TODO : here we read the definition from annotations // System.out.println("resolving from configuration for " // + uiId.getClass()); return null; } protected AbstractComponent loadUI(String uri) { if (getModelPage() != null && getModelPage().eResource() != null && getModelPage().eResource().getResourceSet() != null) this.resourceSet = getModelPage().eResource().getResourceSet(); if (this.resourceSet == null) this.resourceSet = new ResourceSetImpl(); try { Resource resource = this.resourceSet.getResource( URI.createURI(uri), true); if (resource != null && !resource.getContents().isEmpty() && resource.getContents().get(0) instanceof AbstractComponent) return (AbstractComponent) resource.getContents().get(0); } catch (Throwable t) { t.printStackTrace(); // TODO : log this } return null; } public void refresh(AbstractComponent component) { List<PropertyChangedEventAdapter> adapters = getAllRelatedPropertyChangedEventAdapters( component, "input"); //$NON-NLS-1$ for (PropertyChangedEventAdapter adapter : adapters) { adapter.getEventHandlerAdapter().trigger( (Event) adapter.getTarget()); } } protected void registerSelectionProcessorMethods( AbstractCodeDescriptor codeDescriptor) { getObjectMethodDescriptor = codeDescriptor .getMethodDescriptor( "getObject", new String[] { "object" }, new Class[] { Object.class }, Object.class); //$NON-NLS-1$ //$NON-NLS-2$ } protected void registerUIselectorMethods( AbstractCodeDescriptor codeDescriptor) { getUiMethodDescriptor = codeDescriptor.getMethodDescriptor("getUi", new String[] { "element", "uiId" }, new Class[] { Object.class, Object.class }, AbstractComponent.class); //$NON-NLS-1$ getUiIdMethodDescriptor = codeDescriptor.getMethodDescriptor("getUiId", new String[] { "element" }, new Class[] { Object.class }, Object.class); //$NON-NLS-1$ getUiURIMethodDescriptor = codeDescriptor .getMethodDescriptor( "getUiURI", new String[] { "element", "uiId" }, new Class[] { Object.class, Object.class }, String.class); //$NON-NLS-1$ } protected void releaseCodeDescriptor(AbstractCodeDescriptor codeDescriptor) { if (codeDescriptor != null && codeDescriptor.isInstanciated()) { AbstractCodeDescriptor.MethodDescriptor releaseMethodDescriptor = getReleaseMethodDescriptor(codeDescriptor); if (releaseMethodDescriptor != null) codeDescriptor.invokeMethod(releaseMethodDescriptor, null); } } protected AbstractComponent resolveUI(Object input, Object uiId) { AbstractComponent ui = uiIdToUiRegistry.get(uiId); if (ui != null) return ui; String uri = null; if (uri == null || "".equals(uri)) { //$NON-NLS-1$ uri = getURIFromConfiguration(uiId); if (uri == null || "".equals(uri)) //$NON-NLS-1$ if (getGetUiURIMethodDescriptor() != null) uri = (String) getUiSelectorCodeDescriptor().invokeMethod( getGetUiURIMethodDescriptor(), new Object[] { input, uiId }); } if (uri != null && !"".equals(uri)) { //$NON-NLS-1$ ui = loadUI(uri); if (ui != null) { uiIdToUiRegistry.put(uiId, ui); return ui; } } else if (getGetUiMethodDescriptor() != null) ui = (AbstractComponent) getUiSelectorCodeDescriptor() .invokeMethod(getGetUiMethodDescriptor(), new Object[] { input, uiId }); if (ui == null) ui = BLANK_CONTAINER; uiIdToUiRegistry.put(uiId, ui); return ui; } public void setFocus() { if (getControl() != null && !getControl().isDisposed()) getControl().setFocus(); } protected void setInput(AbstractComponent component, Object input) { if (component == BLANK_CONTAINER) return; List<PropertyChangedEventAdapter> adapters = getAllRelatedPropertyChangedEventAdapters( component, "input"); //$NON-NLS-1$ component.set("input", input); //$NON-NLS-1$ for (PropertyChangedEventAdapter adapter : adapters) { adapter.attachListeners(); adapter.getEventHandlerAdapter().trigger( (Event) adapter.getTarget()); } } protected void unsetInput(AbstractComponent component) { if (component == BLANK_CONTAINER) return; List<PropertyChangedEventAdapter> adapters = getAllRelatedPropertyChangedEventAdapters( component, "input"); for (PropertyChangedEventAdapter adapter : adapters) adapter.detachListeners(); } protected SWTControlViewer getViewer() { return viewer; } protected void setViewer(SWTControlViewer viewer) { this.viewer = viewer; } protected Page getModelPage() { return modelPage; } protected void setModelPage(Page modelPage) { this.modelPage = modelPage; } }