/***************************************************************************** * Copyright (c) 2006-2008 g-Eclipse Consortium * 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 * * Initial development of the original code was made for the * g-Eclipse project founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributors: * Mathias Stuempert - initial API and implementation * Ariel Garcia - updated to new problem reporting *****************************************************************************/ package eu.geclipse.core.internal.model; import java.util.ArrayList; import java.util.Collection; import java.util.Hashtable; import java.util.List; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import eu.geclipse.core.ICoreProblems; import eu.geclipse.core.internal.Activator; import eu.geclipse.core.internal.model.notify.GridModelEvent; import eu.geclipse.core.model.GridModel; import eu.geclipse.core.model.IGridContainer; import eu.geclipse.core.model.IGridElement; import eu.geclipse.core.model.IGridElementCreator; import eu.geclipse.core.model.IGridElementManager; import eu.geclipse.core.model.IGridModelEvent; import eu.geclipse.core.model.IGridModelListener; import eu.geclipse.core.model.IGridProject; import eu.geclipse.core.model.impl.AbstractGridElement; import eu.geclipse.core.reporting.ProblemException; /** * Internal abstract implementation of an {@link IGridElementManager}. */ public abstract class AbstractGridElementManager extends AbstractGridElement implements IGridElementManager { /** * The internal element table that holds the managed elements. */ private Hashtable< IPath, IGridElement > elements = new Hashtable< IPath, IGridElement >(); /** * The list of {@link IGridModelListener}s. */ private List< IGridModelListener > listeners = new ArrayList< IGridModelListener >(); /** * Standard constructor. */ protected AbstractGridElementManager() { super(); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridModelNotifier#addGridModelListener(eu.geclipse.core.model.IGridModelListener) */ public void addGridModelListener( final IGridModelListener listener ) { if ( !this.listeners.contains( listener ) ) { this.listeners.add( listener ); } } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#canContain(eu.geclipse.core.model.IGridElement) */ public boolean canContain( final IGridElement element ) { return canManage( element ); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#contains(eu.geclipse.core.model.IGridElement) */ public boolean contains( final IGridElement element ) { return this.elements.values().contains( element ); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#create(eu.geclipse.core.model.IGridElementCreator) */ public IGridElement create( final IGridElementCreator creator ) throws ProblemException { IGridElement newElement = creator.create( this ); if ( newElement != null ) { addElement( newElement ); } return newElement; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#delete(eu.geclipse.core.model.IGridElement) */ public void delete( final IGridElement child ) { if ( removeElement( child ) ) { child.dispose(); } } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#deleteAll() */ public void deleteAll() { if ( ( this.elements != null ) && !this.elements.isEmpty() ) { Collection< IGridElement > values = this.elements.values(); for ( IGridElement element : values ) { element.dispose(); } IGridElement[] elementArray = values.toArray( new IGridElement[ this.elements.size() ] ); fireGridModelEvent( IGridModelEvent.ELEMENTS_REMOVED, elementArray ); this.elements.clear(); } } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#findChild(java.lang.String) */ public IGridElement findChild( final String name ) { IGridElement result = null; for ( IGridElement element : this.elements.values() ) { if ( element.getName().equals( name ) ) { result = element; break; } } return result; } /** * Try to find the element with the specified path. * * @param path The path of the element. * @return The element matching the specified path or * <code>null</code> if no such element could be found. */ public IGridElement findChild( final IPath path ) { return this.elements.get( path ); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#findChildWithResource(java.lang.String) */ public IGridElement findChildWithResource( final String resourceName ) { IGridElement result = null; for ( IGridElement element : this.elements.values() ) { IResource resource = element.getResource(); if ( resource != null ) { if ( resource.getName().equals( resourceName ) ) { result = element; break; } } } return result; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#getChildCount() */ public int getChildCount() { return this.elements.size(); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#getChildren() */ public IGridElement[] getChildren( final IProgressMonitor monitor ) { Collection< IGridElement > values = this.elements.values(); return values.toArray( new IGridElement[ values.size() ] ); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#hasChildren() */ public boolean hasChildren() { return !this.elements.isEmpty(); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#isDirty() */ public boolean isDirty() { return false; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridElement#getFileStore() */ public IFileStore getFileStore() { IFileStore managerStore = getManagerStore(); IFileStore childStore = managerStore.getChild( getName() ); IFileInfo childInfo = childStore.fetchInfo(); if ( !childInfo.exists() ) { try { childStore.mkdir( EFS.NONE, null ); } catch( CoreException cExc ) { Activator.logException( cExc ); } } return childStore; } /** * Get the {@link IFileStore} were managers store their data. * * @return The file store were all managers should save their * data to. */ public static IFileStore getManagerStore() { Activator activator = Activator.getDefault(); IPath statePath = null; if (activator!=null){ statePath=activator.getStateLocation(); } return EFS.getLocalFileSystem().getStore( statePath ); } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridElement#getParent() */ public IGridContainer getParent() { return GridModel.getRoot(); } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridElement#getPath() */ public IPath getPath() { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IPath rootPath = root.getFullPath(); return rootPath.append( getName() ); } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridElement#getProject() */ @Override public IGridProject getProject() { return null; } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridElement#getResource() */ public IResource getResource() { return null; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#isLazy() */ public boolean isLazy() { return false; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridElement#isLocal() */ public boolean isLocal() { return true; } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridElement#getAdapter(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public Object getAdapter( final Class adapter ) { return null; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#refresh(org.eclipse.core.runtime.IProgressMonitor) */ public void refresh( final IProgressMonitor monitor ) { // empty implementation } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridModelNotifier#removeGridModelListener(eu.geclipse.core.model.IGridModelListener) */ public void removeGridModelListener( final IGridModelListener listener ) { this.listeners.remove( listener ); } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridContainer#setDirty() */ public void setDirty() { // empty implementation } /** * Add the specified element to the managed elements of this manager. * If an old element with the same name exists this old element will * be deleted before the new one is added. * * @param element The element to be added. * @return True if the operation was successful. * @throws ProblemException If an error occurs. */ public boolean addElement( final IGridElement element ) throws ProblemException { boolean result = false; testCanManage( element ); IPath path = element.getPath(); IGridElement oldElement = findChild( path ); if ( element != oldElement ) { if ( oldElement != null ) { delete( oldElement ); } this.elements.put( path, element ); IGridModelEvent event = new GridModelEvent( IGridModelEvent.ELEMENTS_ADDED, this, new IGridElement[] { element } ); fireGridModelEvent( event ); result = true; } return result; } /** * Remove the specified element from this manager. * * @param element The element to be removed. * @return True if the element was found and could be removed. */ public boolean removeElement( final IGridElement element ) { IPath path = element.getPath(); boolean removed = ( this.elements.remove( path ) != null); if ( removed ) { IGridModelEvent event = new GridModelEvent( IGridModelEvent.ELEMENTS_REMOVED, this, new IGridElement[] { element } ); fireGridModelEvent( event ); } return removed; } /** * Issue a new {@link GridModelEvent} of the specified type for the specified * elements and distribute it to all registered listener. * * @param type The event's type. * @param elementArray The elements. * @see #fireGridModelEvent(IGridModelEvent) */ protected void fireGridModelEvent( final int type, final IGridElement[] elementArray ) { if ( ( elementArray != null ) && ( elementArray.length > 0 ) ) { IGridModelEvent event = new GridModelEvent( type, this, elementArray ); fireGridModelEvent( event ); } } /** * Distribute the specified event to all registered * {@link IGridModelListener}s. * * @param event The event to be distributed. */ protected void fireGridModelEvent( final IGridModelEvent event ) { for ( IGridModelListener listener : this.listeners ) { listener.gridModelChanged( event ); } } /** * Test if the specified element can be managed by this manager. * Throw an exception if this is not the case. * * @param element The element to be tested. * @throws ProblemException If the tested element can not be * managed by this manager. */ protected void testCanManage( final IGridElement element ) throws ProblemException { if ( ! canManage( element ) ) { throw new ProblemException( ICoreProblems.MODEL_ELEMENT_NOT_MANAGEABLE, Activator.PLUGIN_ID ); } } }