Skip to main content
summaryrefslogtreecommitdiffstats
blob: 8cfda6a8bbd136235ad6b3b224dcc533765392a0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*******************************************************************************
 * 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);
					}
				}
			}
		}
	}

}

Back to the top