Skip to main content
summaryrefslogtreecommitdiffstats
blob: f83ccd28eef42af8da1397cc0bfaf1e7fd4ee06c (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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
/*******************************************************************************
 * 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 API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060517   131582 mahutch@ca.ibm.com - Mark Hutchinson
 * 20060906   141796 gilberta@ca.ibm.com - Gilbert Andrews
 *******************************************************************************/

package org.eclipse.wst.ws.internal.registry;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.wst.ws.internal.model.v10.registry.Registry;
import org.eclipse.wst.ws.internal.model.v10.rtindex.Index;
import org.eclipse.wst.ws.internal.model.v10.rtindex.RTIndexFactory;
import org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy;
import org.eclipse.wst.ws.internal.plugin.WSPlugin;

/**
 * A typical implementation of <code>IRegistryManager</code>.
 * @author cbrealey
 * @see IRegistryManager
 */
public class RegistryManager implements IRegistryManager
{
	private static String REGISTRY = "Registry";
	private static String TAXONOMY = "Taxonomy";
	private static String XML = "xml";
	private Hashtable taxonomyFinders_;
	private Index index_;
	private GenericResourceFactory resourceFactory_ = new GenericResourceFactory();
	private URL registryURL_= null;
	private String registryPathname_ = null;

	/**
	 * Constructs a new RegistryManager for the index XML file
	 * at the given <code>url</code>.
	 * @param url The URL to the index XML file.
	 */
	RegistryManager ( URL url )
	{
		registryURL_ = url;
		taxonomyFinders_ = new Hashtable();
	}

	/**
	 * Constructs a new RegistryManager for the index XML file
	 * at the given <code>pathname</code>.
	 * @param pathname The pathname to the index XML file.
	 */
	RegistryManager ( String pathname )
	{
		registryPathname_ = pathname;
		taxonomyFinders_ = new Hashtable();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getURL()
	 */
	public URL getURL () throws MalformedURLException
	{
		if (registryURL_ == null)
		{
			registryURL_ = new File(registryPathname_).toURL();
		}
		return registryURL_;
	}

	/**
	 * Returns an absolute URL computed from the absolute URL of the
	 * index XML document managed by this <code>RegistryManager</code>
	 * and the given <code>id</code>. This method is used to determine
	 * a reasonable location URL for registry and taxonomy documents
	 * when references to them are first to be added to the index XML
	 * document. This method is idempotent insofar as it will always
	 * compute the same URL for a given <code>RegistryManager</code>
	 * and a given <code>id</code>.
	 * 
	 * @param id The id of the referenced registry or taxonomy document. 
	 * @return The absolute URL to the referenced document.
	 * @throws MalformedURLException If a viable absolute URL cannot
	 * be computed.
	 */
	private URL getURL ( String id ) throws MalformedURLException
	{
		String baseUrl = ""; 
		URL indexUrl = getURL();
		String indexString = indexUrl.toString();
		int index = indexString.lastIndexOf("/"); 
		baseUrl = indexString.substring(0,index + 1);
		String urlString = baseUrl + id + "." + XML;
		return new URL(urlString);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#refreshManager()
	 */
	public void refreshManager ()
	{
		index_ = null;
	}
	
	/**
	 * Caches and returns the index model. On first call,
	 * if an index document exists, the index is loaded
	 * from it, otherwise, a new index is returned.
	 * @return The index.
	 * @throws CoreException If the index cannot be loaded for any reason.
	 */
	private Index getIndex () throws CoreException
	{
		if (index_ == null)
		{
			try
			{
				URL indexURL = getURL();
				if (RegistryService.exists(indexURL))
				{
					Resource resource = resourceFactory_.createResource(URI.createURI("*.xml"));
					resource.load(RegistryService.getInputStreamFor(indexURL),null);
					org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot document = (org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot)resource.getContents().get(0);
					index_ = document.getIndex();
				}
				else
				{
					index_ = RTIndexFactory.eINSTANCE.createIndex();
				}
			}
			catch (IOException e)
			{
				//TODO: Need a message for this Status.
				throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",e));
			}
		}
		return index_;
	}

	/**
	 * Saves the index model to an XML document.	
	 * @throws CoreException If the save fails for any reason.
	 */
	private void saveIndex () throws CoreException
	{
		org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot document = RTIndexFactory.eINSTANCE.createDocumentRoot();
		document.setIndex(getIndex());
		Resource resource = resourceFactory_.createResource(URI.createURI("*.xml"));
		resource.getContents().add(document);
		try
		{
			resource.save(RegistryService.getOutputStreamFor(getURL()),null);
		}
		catch (IOException e)
		{
			//TODO: Need a message for this Status.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",e));
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#addTaxonomyFinder(java.lang.String, org.eclipse.wst.ws.internal.registry.ITaxonomyFinder)
	 */
	public void addTaxonomyFinder(String className, ITaxonomyFinder taxonomyFinder)
	{
		taxonomyFinders_.put(className,taxonomyFinder);
	}
	
	/**
	 * Adds the given <code>registry</code> as-is, whether full model
	 * or reference, to the index only if a registry with the same ID
	 * or reference is not already stored there.
	 * @param registry The registry to add.
	 */
	private void addRegistryToIndex(Registry registry) throws CoreException
	{
		String id = registry.getId();
		if (id == null) id = registry.getRef();
		if (id != null && getRegistry(id) == null)
		{
			getIndex().getRegistry().add(registry);
		}
	}
	
	/**
	 * Adds the given <code>taxonomy</code> as-is, whether full model
	 * or reference, to the index only if a taxonomy with the same ID
	 * or reference is not already stored there.
	 * @param taxonomy The taxonomy to add.
	 */
	private void addTaxonomyToIndex(Taxonomy taxonomy) throws CoreException
	{
		String id = taxonomy.getId();
		if (id == null) id = taxonomy.getRef();
		if (id != null && getTaxonomy(id) == null)
		{
		 	getIndex().getTaxonomy().add(taxonomy);	
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#saveRegistry(org.eclipse.wst.ws.internal.model.v10.registry.Registry)
	 */
	public Registry saveRegistry ( Registry registry ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		Registry registryRef = null;
		try
		{
			URL url = getURL(REGISTRY + registry.getId());
			registryService.saveRegistry(url,registry);
			registryRef = registryService.newRegistryReference(registry);
			registryRef.setLocation(url.toString());
			addRegistryToIndex(registryRef);
			saveIndex();
			/*
			 * TODO: The following pile of code is commented out
			 * since there isn't a reliable way under the current
			 * design to save taxonomy models held in a registry model
			 * 
			ITaxonomyFinder finder = (ITaxonomyFinder)taxonomyFinders_.get(registry.getClass().getName());
			if (finder != null)
			{
				Taxonomy[] taxonomies = finder.taxonomies(registry);
				for (int i=0; i<taxonomies.length; i++)
				{
					String id = taxonomies[i].getId();
					String ref = taxonomies[i].getRef();
					if (id != null)
					{
						URL taxonomyURL = getURL(TAXONOMY + id);
						registryService.saveTaxonomy(taxonomyURL,taxonomies[i]);
						Taxonomy taxonomyRef = registryService.newTaxonomyReference(taxonomies[i]);
						taxonomyRef.setLocation(taxonomyURL.toString());
						addTaxonomyToIndex(taxonomyRef);
					}
					else if (ref != null)
					{
						if (taxonomies[i].getLocation() == null)
						{
							String location = null;
							Taxonomy taxonomy = getTaxonomy(ref);
							if (taxonomy != null) location = taxonomy.getLocation();
							if (location == null) location = getURL(TAXONOMY + ref).toString();
							taxonomies[i].setLocation(location);
							if (taxonomy == null)
							{
								addTaxonomyToIndex(registryService.newTaxonomyReference(taxonomies[i]));
							}
						}
					}
				}
			}
		    */
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
		return registryService.newRegistryReference(registryRef);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadRegistry(java.lang.String)
	 */
	public Registry loadRegistry ( String uri ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		try
		{
			Registry registry = getRegistry(uri);
			if (registry == null) return null;

			// If the Registry has an ID, it's a full model
			// inlined within the Index and is returned as-is.
			if (registry.getId() != null) return registry;

			// Otherwise it's a reference to a full model
			// which we load from the reference's location.
			String urlString = registry.getLocation();
			if (urlString == null) return null;
			URL url = new URL(urlString);
			return registryService.loadRegistry(url);
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadRegistries(java.lang.String[])
	 */
	public Registry[] loadRegistries ( String[] uris ) throws CoreException
	{
		List list = new ArrayList(uris.length);
		for (int i=0; i<uris.length; i++)
		{
			Registry registry = loadRegistry(uris[i]);
			if (registry != null)
			{
				list.add(registry);
			}
		}
		return (Registry[])list.toArray(new Registry[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getRegistryURIs()
	 */
	public String[] getRegistryURIs () throws CoreException
	{
		EList list = getIndex().getRegistry();
		List registryURIs = new ArrayList(list.size());
		Iterator iterator = list.iterator();
		while(iterator.hasNext())
		{
			// Each Registry found in the index may be
			// either a full model or a reference to one.
			Registry registry = (Registry)iterator.next();
			if (registry.getId() != null)
			{
				registryURIs.add(registry.getId());
			}
			else if (registry.getRef() != null)
			{
				registryURIs.add(registry.getRef());
			}
		}	
		return (String[])registryURIs.toArray(new String[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#removeRegistry(java.lang.String, boolean)
	 */
	public void removeRegistry ( String uri, boolean deleteDocument ) throws CoreException
	{
		EList list = getIndex().getRegistry();
		Registry registry = getRegistry(uri);
		if (registry != null)
		{
			list.remove(registry);
			saveIndex();
			// The identified Registry may be either a full model
			// (ie. inlined in the Index) or a reference to one.
			// Only in the latter case is there a file to delete.
			if (deleteDocument && registry.getLocation() != null)
			{
				//TODO: Implement me.
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#saveTaxonomy(org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy)
	 */
	public Taxonomy saveTaxonomy ( Taxonomy taxonomy ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		Taxonomy taxonomyRef = null;
		try
		{
			URL	url = getURL(TAXONOMY + taxonomy.getId());
		    registryService.saveTaxonomy(url,taxonomy);
			taxonomyRef = registryService.newTaxonomyReference(taxonomy);
			taxonomyRef.setLocation(url.toString());
			addTaxonomyToIndex(taxonomyRef);
			saveIndex();
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
		return registryService.newTaxonomyReference(taxonomyRef);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadTaxonomy(java.lang.String)
	 */
	public Taxonomy loadTaxonomy ( String uri ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		try
		{
			Taxonomy taxonomy = getTaxonomy(uri);
			if (taxonomy == null) return null;

			// If the Taxonomy has an ID, it's a full model
			// inlined within the Index and is returned as-is.
			if (taxonomy.getId() != null) return taxonomy;

			// Otherwise it's a reference to a full model
			// which we load from the reference's location.
			String urlString = taxonomy.getLocation();
			if (urlString == null) return null;
			URL url = new URL(urlString);
			return registryService.loadTaxonomy(url);
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadTaxonomies(java.lang.String[])
	 */
	public Taxonomy[] loadTaxonomies ( String[] uris ) throws CoreException
	{
		List list = new ArrayList(uris.length);
		for (int i=0; i<uris.length; i++)
		{
			Taxonomy taxonomy = loadTaxonomy(uris[i]);
			if (taxonomy != null)
			{
				list.add(taxonomy);
			}
		}
		return (Taxonomy[])list.toArray(new Taxonomy[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getTaxonomyURIs()
	 */
	public String[] getTaxonomyURIs () throws CoreException
	{
		EList list = getIndex().getTaxonomy();
		List taxonomyURIs = new ArrayList(list.size());
		Iterator iterator = list.iterator();
		while(iterator.hasNext())
		{
			// Each Taxonomy found in the index may be
			// either a full model or a reference to one.
			Taxonomy taxonomy = (Taxonomy)iterator.next();
			if (taxonomy.getId() != null)
			{
				taxonomyURIs.add(taxonomy.getId());
			}
			else if (taxonomy.getRef() != null)
			{
				taxonomyURIs.add(taxonomy.getRef());
			}
		}	
		return (String[])taxonomyURIs.toArray(new String[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#removeTaxonomy(java.lang.String, boolean)
	 */
	public void removeTaxonomy ( String uri, boolean deleteDocument ) throws CoreException
	{
		EList list = getIndex().getTaxonomy();
		Taxonomy taxonomy = getTaxonomy(uri);
		if (taxonomy != null)
		{
			list.remove(taxonomy);
			saveIndex();
			// The identified Taxonomy may be either a full model
			// (ie. inlined in the Index) or a reference to one.
			// Only in the latter case is there a file to delete.
			if (deleteDocument && taxonomy.getLocation() != null)
			{
				//TODO: Implement me.
			}
		}
	}

	/**
	 * Returns the Registry from the index whose ID or Reference
	 * matches the given URI. As such, this method may return a
	 * full model or a reference to a full model.
	 * @param uri The URI identifier of the Registry
	 * @return The <code>Registry</code> object whose ID or reference
	 * matches the given <code>uri</code>, or null if none match.
	 */
    private Registry getRegistry ( String uri ) throws CoreException
    {
		EList list = getIndex().getRegistry();	
		Iterator it = list.iterator();
		while (it.hasNext()){
			Registry registry = (Registry)it.next();
			if (uri.equals(registry.getId()) || uri.equals(registry.getRef())){
				return registry;  
			}
		}	
        return null;
    }
	
	/**
	 * Returns the Taxonomy from the index whose ID or Reference
	 * matches the given URI. As such, this method may return a
	 * full model or a reference to a full model.
	 * @param uri The URI identifier of the Taxonomy
	 * @return The <code>Taxonomy</code> object whose ID or reference
	 * matches the given <code>uri</code>, or null if none match.
	 */
    private Taxonomy getTaxonomy ( String uri ) throws CoreException
    {
		EList list = getIndex().getTaxonomy();	
		Iterator it = list.iterator();
		while (it.hasNext()){
			Taxonomy taxonomy = (Taxonomy)it.next();
			if (uri.equals(taxonomy.getId()) || uri.equals(taxonomy.getRef())){
				return taxonomy;
			}
		}	
        return null;
	}
}

Back to the top