/***************************************************************************** * 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 *****************************************************************************/ package eu.geclipse.core.internal.model; import java.util.List; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.IScopeContext; import org.osgi.framework.Bundle; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; import eu.geclipse.core.ExtensionManager; import eu.geclipse.core.Extensions; import eu.geclipse.core.internal.Activator; import eu.geclipse.core.internal.model.notify.GridModelEvent; import eu.geclipse.core.internal.model.notify.GridNotificationService; import eu.geclipse.core.model.IGridContainer; import eu.geclipse.core.model.IGridElement; import eu.geclipse.core.model.IGridModelEvent; import eu.geclipse.core.model.IGridProject; import eu.geclipse.core.model.IVirtualOrganization; import eu.geclipse.core.model.impl.ResourceGridContainer; import eu.geclipse.core.project.GridProjectNature; import eu.geclipse.core.reporting.ProblemException; /** * This is the grid model class that represents any project in the * workspace. This has not to be necessarily a grid project. Use the * {@link #hasGridNature()} method to determine if this is really a * grid project. */ public class GridProject extends ResourceGridContainer implements IGridProject { /** * ID of the preference node for grid projects. */ public static final String PROJECT_NODE = "eu.geclipse.core"; //$NON-NLS-1$ /** * ID of the preference folder node for grid projects. */ public static final String PROJECT_FOLDER_NODE = "eu.geclipse.core.folders"; //$NON-NLS-1$ private static final String VO_ATTRIBUTE = "vo"; //$NON-NLS-1$ private static final QualifiedName PROJECT_FOLDER_ID_QN = new QualifiedName( Activator.PLUGIN_ID, "grid.project.folder.id" ); //$NON-NLS-1$ private ProjectVo vo; /** * Default constructor that constructs a grid project out of an * ordinary <code>IProject</code> object. * * @param project The <code>IProject</code> that corresponds to this * grid project. */ protected GridProject( final IProject project ) { super( project ); loadProjectProperties( project ); } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridContainer#canContain(eu.geclipse.core.model.IGridElement) */ @Override public boolean canContain( final IGridElement element ) { return true; } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridContainer#getChildren(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IGridElement[] getChildren( final IProgressMonitor monitor ) throws ProblemException { IGridElement[] children = new IGridElement[0]; if ( isOpen() ) { children = super.getChildren( monitor ); if ( ! hasVo( children ) ) { loadProjectProperties( ( IProject ) getResource() ); children = super.getChildren( monitor ); } } return children; } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridContainer#getChildCount() */ @Override public int getChildCount() { int result = 0; if ( isOpen() ) { result = super.getChildCount(); } return result; } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridElement#getProject() */ @Override public IGridProject getProject() { return this; } public IGridContainer getProjectFolder( final Class< ? extends IGridElement > elementType ) { IGridContainer result = this; ProjectScope projectScope = new ProjectScope( ( IProject ) getResource() ); Preferences folderNode = projectScope.getNode( PROJECT_FOLDER_NODE ); ExtensionManager extm = new ExtensionManager(); List< IConfigurationElement > configurationElements = extm.getConfigurationElements( Extensions.PROJECT_FOLDER_POINT, Extensions.PROJECT_FOLDER_ELEMENT ); for( IConfigurationElement element : configurationElements ) { String id = element.getAttribute( Extensions.PROJECT_FOLDER_ID_ATTRIBUTE ); String label = folderNode.get( id, null ); if ( label != null ) { String className = element.getAttribute( Extensions.PROJECT_FOLDER_ELEMENTCLASS_ATTRIBUTE ); String contributor = element.getContributor().getName(); Class<?> elementClass = null; Bundle bundle = Platform.getBundle( contributor ); try { elementClass = bundle.loadClass( className ); } catch( ClassNotFoundException exception ) { try { elementClass = Class.forName( className ); } catch ( ClassNotFoundException cnfExc ) { Activator.logException( cnfExc ); } } if( elementClass != null ) { if ( elementClass.equals( elementType ) ) { result = getProjectFolder( label ); break; } else if ( elementClass.isAssignableFrom( elementType ) ) { result = getProjectFolder( label ); } } } } return result; } private LocalFolder getProjectFolder( final String name ) { LocalFolder result = null; IGridElement child = findChild( name ); if ( child == null ) { IProject project = ( IProject ) getResource(); IFolder folder = project.getFolder( name ); if ( ! folder.exists() ) { try { folder.create( IResource.FORCE, true, null ); result = getProjectFolder( name ); } catch (CoreException e) { // Do nothing, just ignore } } } else if ( child instanceof LocalFolder ) { result = ( LocalFolder ) child; } return result; } public IGridContainer getProjectFolder( final IGridElement element ) { return getProjectFolder( element.getClass() ); } public String getProjectFolderID( final IGridContainer folder ) { String result = null; if ( folder.getParent() == this ) { String name = folder.getName(); ProjectScope projectScope = new ProjectScope( ( IProject ) getResource() ); Preferences folderNode = projectScope.getNode( PROJECT_FOLDER_NODE ); try { String[] keys = folderNode.keys(); for ( String key : keys ) { String label = folderNode.get( key, null ); if ( name.equals( label ) ) { result = key; break; } } } catch ( BackingStoreException bsExc ) { Activator.logException( bsExc ); } } return result; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridProject#getVO() */ public IVirtualOrganization getVO() { return this.vo; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridProject#hasGridNature() */ public boolean hasGridNature() { boolean result = false; IProject project = ( IProject ) getResource(); try { result = project.hasNature( GridProjectNature.getID() ); } catch( CoreException e ) { // Don't do anything here, just return false } return result; } /* (non-Javadoc) * @see eu.geclipse.core.model.IGridProject#isOpen() */ public boolean isOpen() { return ( ( IProject ) getResource() ).isOpen(); } @Override protected IGridElement addElement( final IGridElement element ) throws ProblemException { IGridElement result = super.addElement( element ); if ( ( result != null ) && ( result instanceof IGridContainer ) && ! result.isVirtual() ) { try { GridNotificationService.getInstance().lock( this ); boolean updated = updateProjectProperties( ( IGridContainer ) element ); if ( ! updated ) { updateProjectFolderProperties( ( IGridContainer ) element ); } GridNotificationService.getInstance().unlock( this ); } catch ( CoreException cExc ) { Activator.logException( cExc ); } catch ( BackingStoreException bsExc ) { Activator.logException( bsExc ); } } return result; } /* (non-Javadoc) * @see eu.geclipse.core.model.impl.AbstractGridContainer#fetchChildren(org.eclipse.core.runtime.IProgressMonitor) */ @Override protected IStatus fetchChildren( final IProgressMonitor monitor ) { IStatus result = Status.CANCEL_STATUS; if ( isOpen() ) { result = super.fetchChildren( monitor ); } return result; } private boolean hasVo( final IGridElement[] children ) { boolean result = false; for ( IGridElement child : children ) { if ( child instanceof ProjectVo ) { result = true; break; } } return result; } private void loadProjectProperties( final IProject project ) { IScopeContext projectScope = new ProjectScope( project ); Preferences projectNode = projectScope.getNode( PROJECT_NODE ); try { projectNode.sync(); String voName = projectNode.get( VO_ATTRIBUTE, null ); this.vo = null; VoManager voManager = VoManager.getManager(); if ( voName != null ) { IVirtualOrganization globalVo = ( IVirtualOrganization ) voManager.findChild( voName ); if ( globalVo != null ) { this.vo = new ProjectVo( this, globalVo ); addElement( this.vo ); } } } catch ( BackingStoreException bsExc ) { Activator.logException( bsExc ); } catch ( ProblemException pExc ) { Activator.logException( pExc ); } } private boolean updateProjectFolderProperties( final IGridContainer folder ) throws CoreException, BackingStoreException { boolean result = false; String name = folder.getName(); IScopeContext projectScope = new ProjectScope( ( IProject ) getResource() ); Preferences folderNode = projectScope.getNode( PROJECT_FOLDER_NODE ); for ( String id : folderNode.keys() ) { String label = folderNode.get( id, null ); if ( name.equals( label ) ) { IResource resource = folder.getResource(); resource.setSessionProperty( PROJECT_FOLDER_ID_QN, id ); result = true; } } if ( result ) { GridModelEvent event = new GridModelEvent( IGridModelEvent.PROJECT_FOLDER_CHANGED, this, new IGridElement[] { folder } ); GridNotificationService.getInstance().queueEvent( event ); } return result; } private boolean updateProjectProperties( final IGridContainer folder ) throws CoreException { boolean result = false; IResource resource = folder.getResource(); String id = ( String ) resource.getSessionProperty( PROJECT_FOLDER_ID_QN ); String name = folder.getName(); if ( id != null ) { IScopeContext projectScope = new ProjectScope( ( IProject ) getResource() ); final Preferences folderNode = projectScope.getNode( PROJECT_FOLDER_NODE ); String label = folderNode.get( id, null ); if ( ! name.equals( label ) ) { folderNode.put( id, name ); Job syncJob = new Job( "syncProjectPreferences@" + getName() ) { //$NON-NLS-1$ @Override protected IStatus run( final IProgressMonitor monitor ) { IStatus status = Status.OK_STATUS; try { folderNode.flush(); } catch ( BackingStoreException bsExc ) { Activator.logException( bsExc ); status = Status.CANCEL_STATUS; } return status; } }; syncJob.setSystem( true ); syncJob.schedule(); result = true; } } if ( result ) { GridModelEvent event = new GridModelEvent( IGridModelEvent.PROJECT_FOLDER_CHANGED, this, new IGridElement[] { folder } ); GridNotificationService.getInstance().queueEvent( event ); } return result; } }