| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 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 implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.library.layout; |
| |
| import java.io.File; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory; |
| import org.eclipse.emf.edit.provider.ITreeItemContentProvider; |
| import org.eclipse.epf.common.utils.StrUtil; |
| import org.eclipse.epf.library.ILibraryManager; |
| import org.eclipse.epf.library.LibraryPlugin; |
| import org.eclipse.epf.library.LibraryService; |
| import org.eclipse.epf.library.configuration.ConfigurationHelper; |
| import org.eclipse.epf.library.configuration.DefaultElementRealizer; |
| import org.eclipse.epf.library.configuration.ElementRealizer; |
| import org.eclipse.epf.library.edit.IFilter; |
| import org.eclipse.epf.library.edit.TngAdapterFactory; |
| import org.eclipse.epf.library.edit.util.ConfigurableComposedAdapterFactory; |
| import org.eclipse.epf.library.edit.util.Suppression; |
| import org.eclipse.epf.library.edit.util.TngUtil; |
| import org.eclipse.epf.library.layout.diagram.IActivityDiagramService; |
| import org.eclipse.epf.library.layout.elements.AbstractElementLayout; |
| import org.eclipse.epf.library.layout.elements.AbstractProcessElementLayout; |
| import org.eclipse.epf.library.layout.elements.GeneralLayout; |
| import org.eclipse.epf.library.util.LibraryUtil; |
| import org.eclipse.epf.library.util.ResourceHelper; |
| import org.eclipse.epf.uma.Activity; |
| import org.eclipse.epf.uma.MethodConfiguration; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.Process; |
| import org.eclipse.epf.uma.TaskDescriptor; |
| import org.eclipse.epf.uma.WorkBreakdownElement; |
| |
| |
| /** |
| * @author Jinhua Xi |
| * @since 1.0 |
| */ |
| public class ElementLayoutManager { |
| |
| private static final String PACKAGE_NAME = ElementLayoutManager.class |
| .getPackage().getName(); |
| |
| private static final String default_config_path = "noconfig"; //$NON-NLS-1$ |
| |
| private boolean isPublishingMode = false; // default to browsing mode |
| |
| private String publish_dir = null; |
| |
| private MethodConfiguration config = null; |
| |
| private IActivityDiagramService diagramService = null; |
| |
| // need to seperate the adapter factory form content and diagram |
| // diagram adaptor factory should not be rolled up |
| private LayoutAdapterFactory contentLayoutAdapterFactory = null; |
| private LayoutAdapterFactory diagramLayoutAdapterFactory = null; |
| |
| // cache the suppression object for publishing model only |
| // map of proc guid to Suppresiion object |
| private Map supressionMap = null; |
| |
| private IContentValidator validator = null; |
| |
| private ElementRealizer realizer = null; |
| |
| public boolean isPublishingMode() |
| { |
| return this.isPublishingMode; |
| } |
| |
| public ElementLayoutManager() { |
| this(null, null, null, false); |
| } |
| |
| public ElementLayoutManager(MethodConfiguration config) { |
| this(config, null, null, false); |
| } |
| |
| public ElementLayoutManager(MethodConfiguration config, String publishdir, IContentValidator validator, boolean isPublishingMode) { |
| this.validator = validator; |
| this.isPublishingMode = isPublishingMode; |
| |
| if (config != null) { |
| this.config = config; |
| } |
| |
| if (publishdir == null) { |
| publishdir = LayoutResources.getDefaultPublishDir(); |
| if (!publishdir.endsWith(File.separator)) { |
| publishdir += File.separator; |
| } |
| |
| // also append the configuration path |
| if (this.config == null) { |
| publishdir += default_config_path; |
| } else { |
| String str = StrUtil.removeSpecialCharacters(this.config.getName()); |
| if ( str == "" ) { |
| str = Integer.toHexString(this.config.toString().hashCode()); |
| } |
| publishdir += str; |
| } |
| } |
| |
| setPublishDir(publishdir); |
| |
| contentLayoutAdapterFactory = new LayoutAdapterFactory(this.config); |
| diagramLayoutAdapterFactory = new LayoutAdapterFactory(this.config); |
| |
| } |
| |
| /** |
| * Returns the content validator. |
| */ |
| public IContentValidator getValidator() { |
| if (validator == null) { |
| validator = new DefaultContentValidator(getPublishDir()); |
| } |
| return validator; |
| } |
| |
| public ElementRealizer getElementRealizer() { |
| if ( realizer == null ) { |
| realizer = new DefaultElementRealizer(config); |
| realizer.setFilter(contentLayoutAdapterFactory.getFilter()); |
| } |
| |
| return realizer; |
| } |
| |
| public void setElementRealizer(ElementRealizer realizer) { |
| this.realizer = realizer; |
| } |
| |
| public ConfigurableComposedAdapterFactory getWBSAdapterFactory() { |
| return contentLayoutAdapterFactory.wbsAdapterFactory; |
| } |
| |
| public ConfigurableComposedAdapterFactory getTBSAdapterFactory() { |
| return contentLayoutAdapterFactory.tbsAdapterFactory; |
| } |
| |
| public ConfigurableComposedAdapterFactory getWPBSAdapterFactory() { |
| return contentLayoutAdapterFactory.wpbsAdapterFactory; |
| } |
| |
| public ConfigurableComposedAdapterFactory getCBSAdapterFactory() { |
| return contentLayoutAdapterFactory.cbsAdapterFactory; |
| } |
| |
| public ConfigurableComposedAdapterFactory getDiagramAdapterFactory() { |
| return diagramLayoutAdapterFactory.wbsAdapterFactory; |
| } |
| |
| public void setActivityDiagramService(IActivityDiagramService diagramService) { |
| this.diagramService = diagramService; |
| } |
| |
| public IActivityDiagramService getActivityDiagramService() { |
| return this.diagramService; |
| } |
| |
| public Suppression getSuppression(Process proc) |
| { |
| Suppression sup = null; |
| if ( isPublishingMode) |
| { |
| if ( supressionMap == null ) |
| { |
| supressionMap = new HashMap(); |
| } |
| String guid = proc.getGuid(); |
| sup = (Suppression)supressionMap.get(guid); |
| if ( sup == null ) |
| { |
| sup = new Suppression(proc); |
| supressionMap.put(guid, sup); |
| } |
| } |
| else |
| { |
| sup = new Suppression(proc); |
| } |
| |
| return sup; |
| } |
| |
| public void prepareAdaptorFactoriesForProcess(Process proc) |
| { |
| // need to iterate the adaptor factory to generate the adaptor tree |
| prepareAdapterfactoryFor(getCBSAdapterFactory(), proc); |
| prepareAdapterfactoryFor(getTBSAdapterFactory(), proc); |
| prepareAdapterfactoryFor(getWBSAdapterFactory(), proc); |
| prepareAdapterfactoryFor(getWPBSAdapterFactory(), proc); |
| } |
| |
| private void prepareAdapterfactoryFor( |
| ComposedAdapterFactory adapterFactory, Object obj) { |
| if (obj == null || adapterFactory == null) { |
| return; |
| } |
| |
| ITreeItemContentProvider provider = null; |
| |
| if (obj instanceof ITreeItemContentProvider) { |
| provider = (ITreeItemContentProvider) obj; |
| } else { |
| provider = (ITreeItemContentProvider) adapterFactory.adapt(obj, |
| ITreeItemContentProvider.class); |
| } |
| |
| if (provider != null) { |
| Collection items = provider.getChildren(obj); |
| for (Iterator it = items.iterator(); it.hasNext();) { |
| Object rawitem = it.next(); |
| |
| MethodElement item = (MethodElement) LibraryUtil |
| .unwrap(rawitem); |
| if ((item instanceof Activity)) { |
| prepareAdapterfactoryFor(adapterFactory, rawitem); |
| } |
| } |
| } |
| } |
| |
| private IElementLayout createLayout(MethodElement element) { |
| |
| // if the element is an activity, we need to fined the path to the process |
| String path = null; |
| Process owningProc = null; |
| if ( element instanceof Activity ) |
| { |
| Activity act = (Activity)element; |
| path = AbstractProcessElementLayout.getPath(act); |
| owningProc = TngUtil.getOwningProcess(act); |
| } |
| |
| return createLayout(element, owningProc, path); |
| } |
| |
| public IElementLayout createLayout(MethodElement element, |
| Process owningProc, String path) { |
| AbstractElementLayout layout = null; |
| |
| String className; |
| if (ConfigurationHelper.isDescriptionElement(element)) { |
| className = "ContentDescription"; //$NON-NLS-1$ |
| } else if (element instanceof Activity) { |
| className = "Activity"; //$NON-NLS-1$ |
| } else if ((element instanceof WorkBreakdownElement) |
| && !(element instanceof TaskDescriptor)) { |
| className = "WorkBreakdownElement"; //$NON-NLS-1$ // taskdescriptor has it's own layout |
| } else { |
| Class i[] = element.getClass().getInterfaces(); |
| if (i != null && i.length == 1) { |
| className = i[0].getName(); |
| } else { |
| className = element.getClass().getName(); |
| } |
| |
| int index = className.lastIndexOf("."); //$NON-NLS-1$ |
| if (index >= 0) { |
| className = className.substring(index + 1); |
| } |
| } |
| |
| className = PACKAGE_NAME + ".elements." + className + "Layout"; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| try { |
| Class c = Class.forName(className); |
| if (c != null) { |
| layout = (AbstractElementLayout) c.newInstance(); |
| } |
| } catch (Exception ex) { |
| // ex.printStackTrace(); |
| } |
| |
| if (layout == null) { |
| // System.out.println("Layout class '" + className + "' for element |
| // '" + element.getName() + "' not defined. Use GeneralLayout"); |
| layout = new GeneralLayout(); |
| } |
| |
| if (layout instanceof AbstractProcessElementLayout) { |
| ((AbstractProcessElementLayout) layout).init(this, element, |
| owningProc, path); |
| } else { |
| layout.init(this, element); |
| } |
| |
| return layout; |
| } |
| |
| public IElementLayout getLayout(MethodElement element, boolean create) { |
| // String id = element.getGuid(); |
| IElementLayout layout = null; // (IElementLayout)layoutMap.get(id); |
| if ((layout == null) && create) { |
| layout = createLayout(element); |
| // layoutMap.put(id, layout); |
| } |
| |
| return layout; |
| } |
| |
| private static final Pattern p_parameters = Pattern |
| .compile( |
| "\\?proc=(.*?)&path=(.*)?", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$ |
| |
| public IElementLayout getLayout(String url) { |
| |
| Process owningProc = null; |
| String path = null; |
| |
| Matcher m = p_parameters.matcher(url); |
| if (m.find()) { |
| String proc = m.group(1); |
| path = m.group(2); |
| ILibraryManager manager = LibraryService.getInstance() |
| .getCurrentLibraryManager(); |
| if (manager != null) { |
| owningProc = (Process) manager.getMethodElement( |
| proc); |
| } |
| } |
| |
| // MethodElement element = (MethodElement)urlMap.get(url); |
| MethodElement element = ResourceHelper.getElementFromFileName(url); |
| if (element != null) { |
| return createLayout(element, owningProc, path); |
| } else { |
| System.out.println("Can't find element for url '" + url + "'"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return null; |
| |
| } |
| |
| public static String getQueryString(String proc, String path) { |
| return "?" + ResourceHelper.URL_PARAMETER_PROCESS + "=" + proc + "&" |
| + ResourceHelper.URL_PARAMETER_PATH + "=" + path; |
| } |
| |
| public MethodConfiguration getConfiguration() { |
| return this.config; |
| } |
| |
| public void setPublishDir(String path) { |
| this.publish_dir = path; |
| if ( !this.publish_dir.endsWith(File.separator) ) { |
| this.publish_dir += File.separator; |
| } |
| |
| // initialize publishing site if needed |
| init_publishingSite(); |
| |
| } |
| |
| public String getPublishDir() { |
| return this.publish_dir; |
| } |
| |
| private void init_publishingSite() { |
| if ( LibraryPlugin.getDefault().isDebugging() ) { |
| System.out |
| .println("Begin initializing publishing site: " + publish_dir); //$NON-NLS-1$ |
| } |
| |
| // copy the layout files from plugin layout to publishign site |
| LayoutResources.copyLayoutFiles(publish_dir); |
| |
| if ( LibraryPlugin.getDefault().isDebugging() ) { |
| System.out.println("End initializing publishing site: " + publish_dir); //$NON-NLS-1$ |
| } |
| } |
| |
| public void copyLibraryResources() { |
| if ( LibraryPlugin.getDefault().isDebugging() ) { |
| System.out |
| .println("Begin copying library resources to publishing site: " + publish_dir); //$NON-NLS-1$ |
| } |
| |
| // copy library resources from library to publishing site |
| File libRoot = new File(LibraryService.getInstance().getCurrentMethodLibraryPath()); |
| if (libRoot != null) { |
| LayoutResources.copyDir(libRoot.getPath(), publish_dir); |
| } |
| |
| if ( LibraryPlugin.getDefault().isDebugging() ) { |
| System.out |
| .println("End copying library resources to publishing site: " + publish_dir); //$NON-NLS-1$ |
| } |
| } |
| |
| public void clear() { |
| // layoutMap.clear(); |
| |
| if ( supressionMap != null ) |
| { |
| supressionMap.clear(); |
| } |
| |
| contentLayoutAdapterFactory.clear(); |
| diagramLayoutAdapterFactory.clear(); |
| |
| if ( validator != null ) |
| { |
| validator.dispose(); |
| } |
| } |
| |
| public class LayoutAdapterFactory |
| { |
| public ConfigurableComposedAdapterFactory wbsAdapterFactory = null; |
| public ConfigurableComposedAdapterFactory tbsAdapterFactory = null; |
| public ConfigurableComposedAdapterFactory wpbsAdapterFactory = null; |
| public ConfigurableComposedAdapterFactory cbsAdapterFactory = null; |
| |
| ProcessAdapterFactoryFilter configurator = null; |
| |
| public LayoutAdapterFactory(MethodConfiguration methodConfig) |
| { |
| // create adapt factories |
| // |
| if(isPublishingMode()) { |
| wbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createPublishingWBSAdapterFactory(); |
| tbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createPublishingTBSAdapterFactory(); |
| wpbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createPublishingWPBSAdapterFactory(); |
| cbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createPublishingCBSAdapterFactory(); |
| } |
| else { |
| wbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createWBSComposedAdapterFactory(); |
| tbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createTBSComposedAdapterFactory(); |
| wpbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createWPBSComposedAdapterFactory(); |
| cbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE |
| .createProcessComposedAdapterFactory(); |
| } |
| |
| // set configuration filter |
| configurator = new ProcessAdapterFactoryFilter(methodConfig, this); |
| |
| wbsAdapterFactory.setFilter(configurator); |
| tbsAdapterFactory.setFilter(configurator); |
| wpbsAdapterFactory.setFilter(configurator); |
| cbsAdapterFactory.setFilter(configurator); |
| } |
| |
| public IFilter getFilter() { |
| return configurator; |
| } |
| |
| public void clear() |
| { |
| if (wbsAdapterFactory != null) { |
| wbsAdapterFactory.dispose(); |
| wbsAdapterFactory = null; |
| } |
| |
| if (tbsAdapterFactory != null) { |
| tbsAdapterFactory.dispose(); |
| tbsAdapterFactory = null; |
| } |
| |
| if (wpbsAdapterFactory != null) { |
| wpbsAdapterFactory.dispose(); |
| wpbsAdapterFactory = null; |
| } |
| |
| if (cbsAdapterFactory != null) { |
| cbsAdapterFactory.dispose(); |
| cbsAdapterFactory = null; |
| } |
| } |
| } |
| } |
| |