blob: 8cfda6a8bbd136235ad6b3b224dcc533765392a0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 Oracle Corporation.
* 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:
* Oracle - initial API and implementation
*
********************************************************************************/
package org.eclipse.jst.jsf.common.metadata.internal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
/**
* Default class used for loading metadata.
* Loads the source types from extensions defined against the domain.
*
* see org.eclipse.jst.jsf.common.domainLoadingStrategies ext-pt
*/
public class DomainLoadingStrategy implements IDomainLoadingStrategy, IMetaDataObserver {
/**
* Domain id
*/
protected String domain;
private MetaDataModel _model;
private List <IDomainSourceModelType> _sourceTypes;
private List <IMetaDataSourceModelProvider> _sources;
/**
* Constructor
* @param domain
*/
public DomainLoadingStrategy(String domain){
this.domain = domain;
}
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IDomainLoadingStrategy#load(org.eclipse.jst.jsf.common.metadata.internal.MetaDataModel)
*/
public void load(MetaDataModel model) {
this._model = model;
_sourceTypes = loadDomainSourceModelTypes();
sortSourceTypes(_sourceTypes);
_sources = locateMetaDataSourceInstances(_sourceTypes, model);
mergeModel(model, _sources);
}
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IDomainLoadingStrategy#reload()
*/
public void reload() throws ModelNotSetException {
//System.out.println("reload");//debug //$NON-NLS-1$
if (_model == null)
throw new ModelNotSetException();
removeOldLocatorObservers();
_sources = locateMetaDataSourceInstances(_sourceTypes, _model);
mergeModel(_model, _sources);
}
/**
* Responsible for iterating through the sorted list of <code>IMetaDataSourceModelProvider</code>
* and merging the models after first translating the source model as required, into a single mreged model of
* standard metadata Entities and Traits.
* @param model
* @param sources
*/
protected void mergeModel(final MetaDataModel model, final List <IMetaDataSourceModelProvider> sources) {
StandardModelFactory.debug(">> Begin Merge: "+model.getModelContext()+"("+sources.size()+ " sources)", StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
final IMetaDataModelMergeAssistant assistant = createModelMergeAssistant(model);
for (final IMetaDataSourceModelProvider mds : sources){
final Iterator translators = mds.getLocator().getDomainSourceModelType().getTranslators().iterator();
while (translators.hasNext()){
final IMetaDataTranslator translator = (IMetaDataTranslator)translators.next();
if (translator.canTranslate(mds)){
StandardModelFactory.debug(">>> Merging: "+model.getModelContext()+"::"+mds, StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$//$NON-NLS-2$
assistant.setSourceModelProvider(mds);
try {
translator.translate(assistant);
} catch (Exception e) {
StandardModelFactory.debug(">>>> Error during translate/merge of: "+model.getModelContext()+": "+mds, StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$ //$NON-NLS-2$
JSFCommonPlugin.log(IStatus.ERROR, "Error during load of: "+mds, e); //$NON-NLS-1$
}
}
}
}
assistant.setMergeComplete();
StandardModelFactory.debug(">> End Merge: "+model.getModelContext(),StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$
}
/**
* @param model
* @return an instance of a IMetaDataModelMergeAssistant to be used while merging source models
*/
protected IMetaDataModelMergeAssistant createModelMergeAssistant(MetaDataModel model){
return new MetaDataModelMergeAssistantImpl(model);
}
/**
* Allows for subclasses to override the default mechanism for sorting the source types.
* @param sourceTypes
*/
protected void sortSourceTypes(List <IDomainSourceModelType> sourceTypes) {
//allows override
}
/**
* @return list of <code>IDomainSourceModelType</code>s located in the <code>DomainSourceTypesRegistry</code>
* for the specified uri
*/
protected List <IDomainSourceModelType> loadDomainSourceModelTypes() {
return DomainSourceTypesRegistry.getInstance().getDomainSourceTypes(domain);
}
/**
* @param sourceTypes
* @param model
* @return list of <code>IMetaDataSourceModelProvider</code> instances from the domain source types applicable for
* this domain for this particular uri specified in the model
*/
protected List <IMetaDataSourceModelProvider> locateMetaDataSourceInstances(final List <IDomainSourceModelType> sourceTypes, MetaDataModel model) {
final List<IMetaDataSourceModelProvider> sources = new ArrayList<IMetaDataSourceModelProvider>();
final IProject project = getProject(model);
for (final IDomainSourceModelType sourceType : sourceTypes){
final IMetaDataLocator locator = sourceType.getLocator(project);
if (locator != null) {
//We MUST set the sourceType here to associate the handler with locator to use for the source models
locator.setDomainSourceModelType(sourceType);
final List <IMetaDataSourceModelProvider> providers = locator.locateMetaDataModelProviders(model.getModelContext().getModelIdentifier());
if (providers != null && !providers.isEmpty()){
for (final IMetaDataSourceModelProvider provider : providers){
//We MUST set the sourceType here to associate the translators to use for the source models
provider.setLocator(locator);
sources.add(provider);
}
}
//listen for changes
locator.addObserver(this);
}
}
return sources;
}
private IProject getProject(final MetaDataModel model) {
return (IProject)model.getModelContext().getAdapter(IProject.class);
}
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataObserver#notifyMetadataChanged(org.eclipse.jst.jsf.common.metadata.internal.IMetaDataChangeNotificationEvent)
*/
public void notifyMetadataChanged(final IMetaDataChangeNotificationEvent event) {
//for now, if any event occurs, we need to flush the _model so that it will rebuild
_model.setNeedsRefresh();
}
/* (non-Javadoc)
* @see org.eclipse.jst.jsf.common.metadata.internal.IDomainLoadingStrategy#cleanup()
*/
public void cleanup(){
removeOldLocatorObservers();
_sources = null;
_sourceTypes = null;
_model = null;
}
private void removeOldLocatorObservers(){
if (_sources != null){
for (final IMetaDataSourceModelProvider provider : _sources){
if (provider != null) {
final IMetaDataLocator locator = provider.getLocator();
if (locator != null){
locator.removeObserver(this);
locator.setDomainSourceModelType(null);
provider.setLocator(null);
}
}
}
}
}
}