1 package org.simantics.export.core.impl;
\r
4 import java.lang.ref.WeakReference;
\r
5 import java.net.MalformedURLException;
\r
7 import java.util.Arrays;
\r
8 import java.util.Collection;
\r
9 import java.util.Comparator;
\r
10 import java.util.List;
\r
11 import java.util.Map;
\r
13 import org.eclipse.core.runtime.CoreException;
\r
14 import org.eclipse.core.runtime.IConfigurationElement;
\r
15 import org.eclipse.core.runtime.Platform;
\r
16 import org.eclipse.jface.resource.ImageDescriptor;
\r
17 import org.osgi.service.prefs.Preferences;
\r
18 import org.simantics.databoard.binding.mutable.Variant;
\r
19 import org.simantics.databoard.type.RecordType;
\r
20 import org.simantics.export.core.ExportContext;
\r
21 import org.simantics.export.core.ExportExtensionPoint;
\r
22 import org.simantics.export.core.error.ExportException;
\r
23 import org.simantics.export.core.intf.ContentType;
\r
24 import org.simantics.export.core.intf.ContentTypeAction;
\r
25 import org.simantics.export.core.intf.DiscoverAction;
\r
26 import org.simantics.export.core.intf.Discoverer;
\r
27 import org.simantics.export.core.intf.ExportClass;
\r
28 import org.simantics.export.core.intf.Exporter;
\r
29 import org.simantics.export.core.intf.Format;
\r
30 import org.simantics.export.core.intf.FormatClass;
\r
31 import org.simantics.export.core.intf.IconResolver;
\r
32 import org.simantics.export.core.intf.ImportAction;
\r
33 import org.simantics.export.core.intf.Importer;
\r
34 import org.simantics.export.core.intf.Publisher;
\r
35 import org.simantics.export.core.intf.PublisherClass;
\r
36 import org.simantics.export.core.manager.Content;
\r
37 import org.simantics.utils.datastructures.ToStringComparator;
\r
40 * Light-weight registry implementation to export extension point.
\r
42 * @author toni.kalajainen@semantum.fi
\r
44 public class ExportExtensionPointImpl implements ExportExtensionPoint {
\r
46 public static final String EP = "org.simantics.export.core.export";
\r
48 Importer[] importers = createImporters();
\r
49 Exporter[] exporters = createExporters();
\r
50 Format[] formats = createFormats();
\r
51 ContentType[] contentTypes = createContentTypes();
\r
52 Discoverer[] discoverers = createDiscoverers();
\r
53 Publisher[] publishers = createPublishers();
\r
55 public ExportExtensionPointImpl() {}
\r
57 public Discoverer[] getDiscoverers(String contentTypeId) {
\r
59 for ( Discoverer discoverer : discoverers ) {
\r
60 if ( contentTypeId.equals( discoverer.contentTypeId() ) ) count++;
\r
63 Discoverer[] result = new Discoverer[ count ];
\r
65 for ( Discoverer discoverer : discoverers ) {
\r
66 if ( contentTypeId.equals( discoverer.contentTypeId() ) ) {
\r
67 result[ i++ ] = discoverer;
\r
74 public Format getFormat(String formatId)
\r
76 for ( Format format : formats ) {
\r
77 if ( formatId.equals( format.id() ) ) return format;
\r
83 public Format getFormatByExt(String fileExt) {
\r
84 for ( Format format : formats ) {
\r
85 if ( fileExt.equals( format.fileext() ) ) return format;
\r
89 public ContentType getContentType(String contentTypeId)
\r
90 //throws ExportException
\r
92 for ( ContentType contentType : contentTypes ) {
\r
93 if ( contentTypeId.equals( contentType.id() ) ) return contentType;
\r
95 //throw new ExportException("ContentType "+contentTypeId+" does not exist");
\r
99 public Importer getImporter(String formatId)
\r
100 //throws ExportException
\r
102 for ( Importer importer : importers ) {
\r
103 if ( formatId.equals( importer.formatId() ) ) return importer;
\r
105 //throw new ExportException("Importer "+formatId+" does not exist");
\r
109 public Exporter[] getExporters(String formatId, String contentTypeId)
\r
112 for ( Exporter exporter : exporters ) {
\r
113 if ( exporter.formatId().equals(formatId) &&
\r
114 exporter.contentTypeId().equals(contentTypeId) ) count++;
\r
116 Exporter[] result = new Exporter[ count ];
\r
118 for ( Exporter exporter : exporters ) {
\r
119 if ( formatId.equals( exporter.formatId() ) && contentTypeId.equals( exporter.contentTypeId() ) ) {
\r
120 result[ index++ ] = exporter;
\r
127 public Exporter[] getExportersForContentType(String contentTypeId)
\r
128 //throws ExportException
\r
131 for ( Exporter exporter : exporters ) {
\r
132 if ( contentTypeId.equals( exporter.contentTypeId() ) ) count++;
\r
135 Exporter[] result = new Exporter[ count ];
\r
137 for ( Exporter exporter : exporters ) {
\r
138 if ( contentTypeId.equals( exporter.contentTypeId() ) ) {
\r
139 result[ i++ ] = exporter;
\r
143 Arrays.sort(result, exporterPrioritySorter);
\r
148 public Exporter[] getExportersForFormat(String formatId)
\r
151 for ( Exporter exporter : exporters ) {
\r
152 if ( formatId.equals( exporter.formatId() ) ) count++;
\r
155 Exporter[] result = new Exporter[ count ];
\r
157 for ( Exporter exporter : exporters ) {
\r
158 if ( formatId.equals( exporter.formatId() ) ) {
\r
159 result[ i++ ] = exporter;
\r
163 Arrays.sort(result, exporterPrioritySorter);
\r
168 public Publisher getPublisher(String publisherId) {
\r
169 for ( Publisher publisher : publishers ) {
\r
170 if ( publisherId.equals( publisher.id() ) ) return publisher;
\r
175 public int getPublisherIndex(String publisherId) {
\r
176 for (int i=0; i<publishers.length; i++) {
\r
177 if ( publisherId.equals( publishers[i].id() ) ) return i;
\r
182 public Publisher getPublisherByLabel(String publisherLabel) {
\r
183 for ( Publisher publisher : publishers ) {
\r
184 if ( publisher.label().equals(publisherLabel ) ) return publisher;
\r
189 ContentType[] createContentTypes() {
\r
190 IConfigurationElement ces[] = Platform.getExtensionRegistry().getConfigurationElementsFor( EP );
\r
192 for (IConfigurationElement ce : ces) {
\r
193 if ( "content_type".equals(ce.getName() ) ) count++;
\r
196 ContentType[] result = new ContentType[count];
\r
198 for (IConfigurationElement ce : ces) {
\r
199 if ( "content_type".equals(ce.getName() ) ) {
\r
200 result[i++] = new ContentTypeImpl( ce );
\r
207 Discoverer[] createDiscoverers() {
\r
208 IConfigurationElement ces[] = Platform.getExtensionRegistry().getConfigurationElementsFor( EP );
\r
210 for (IConfigurationElement ce : ces) {
\r
211 if ( "discoverer".equals(ce.getName() ) ) count++;
\r
214 Discoverer[] result = new Discoverer[count];
\r
216 for (IConfigurationElement ce : ces) {
\r
217 if ( "discoverer".equals(ce.getName() ) ) {
\r
218 result[i++] = new DiscovererImpl( ce );
\r
225 Format[] createFormats() {
\r
226 IConfigurationElement ces[] = Platform.getExtensionRegistry().getConfigurationElementsFor( EP );
\r
228 for (IConfigurationElement ce : ces) {
\r
229 if ( "format".equals(ce.getName() ) ) count++;
\r
232 Format[] result = new Format[count];
\r
234 for (IConfigurationElement ce : ces) {
\r
235 if ( "format".equals(ce.getName() ) ) {
\r
236 result[i++] = new FormatImpl( ce );
\r
243 Exporter[] createExporters() {
\r
244 IConfigurationElement ces[] = Platform.getExtensionRegistry().getConfigurationElementsFor( EP );
\r
246 for (IConfigurationElement ce : ces) {
\r
247 if ( "exporter".equals(ce.getName() ) ) count++;
\r
250 Exporter[] result = new Exporter[count];
\r
252 for (IConfigurationElement ce : ces) {
\r
253 if ( "exporter".equals(ce.getName() ) ) {
\r
254 result[i++] = new ExporterImpl( ce );
\r
261 Importer[] createImporters() {
\r
262 IConfigurationElement ces[] = Platform.getExtensionRegistry().getConfigurationElementsFor( EP );
\r
264 for (IConfigurationElement ce : ces) {
\r
265 if ( "importer".equals(ce.getName() ) ) count++;
\r
268 Importer[] result = new Importer[count];
\r
270 for (IConfigurationElement ce : ces) {
\r
271 if ( "importer".equals(ce.getName() ) ) {
\r
272 result[i++] = new ImporterImpl( ce );
\r
279 Publisher[] createPublishers() {
\r
280 IConfigurationElement ces[] = Platform.getExtensionRegistry().getConfigurationElementsFor( EP );
\r
282 for (IConfigurationElement ce : ces) {
\r
283 if ( "publisher".equals(ce.getName() ) ) count++;
\r
286 Publisher[] result = new Publisher[count];
\r
288 for (IConfigurationElement ce : ces) {
\r
289 if ( "publisher".equals(ce.getName() ) ) {
\r
290 result[i++] = new PublisherImpl( ce );
\r
294 Arrays.sort(result, new ToStringComparator.ByLength());
\r
299 static class ContentTypeImpl implements ContentType {
\r
300 IConfigurationElement ce;
\r
301 ContentTypeAction action;
\r
302 WeakReference<IconResolver> resolverCache = null;
\r
303 boolean invalidIconResolver = false;
\r
305 public ContentTypeImpl(IConfigurationElement ce) {
\r
309 ContentTypeAction getOrCreate() throws ExportException {
\r
310 if ( action == null ) {
\r
312 String value = ce.getAttribute("contentTypeAction");
\r
313 if ( value == null ) return new DefaultContentTypeAction();
\r
314 action = (ContentTypeAction) ce.createExecutableExtension("contentTypeAction");
\r
315 } catch (CoreException e) {
\r
316 throw new ExportException( e );
\r
323 public String id() {
\r
324 return ce.getAttribute("id");
\r
328 public String label() {
\r
329 return ce.getAttribute("label");
\r
333 public String plural() {
\r
334 return ce.getAttribute("plural");
\r
337 public ImageDescriptor icon(String contentUri) {
\r
338 if (!invalidIconResolver && ce.getAttribute("iconResolver") != null) {
\r
340 IconResolver resolver = resolverCache != null ? resolverCache.get() : null;
\r
341 if (resolver == null) {
\r
342 resolver = (IconResolver) ce.createExecutableExtension("iconResolver");
\r
343 resolverCache = new WeakReference<IconResolver>(resolver);
\r
345 return resolver.get(contentUri);
\r
346 } catch (CoreException e) {
\r
347 // Invalid iconResolver, could not instantiate.
\r
348 // Don't try to resolve it anymore if it fails once.
\r
349 invalidIconResolver = true;
\r
357 public ImageDescriptor icon() {
\r
359 String _url = ce.getAttribute("icon");
\r
360 URL url = new URL(_url);
\r
361 return ImageDescriptor.createFromURL(url);
\r
362 } catch (MalformedURLException e) {
\r
368 public boolean isModel() {
\r
369 return "true".equalsIgnoreCase(ce.getAttribute("model"));
\r
373 public String toString() {
\r
374 return "ContentType, id="+id()+", label="+label();
\r
378 public Map<String, String> getLabels(ExportContext ctx, Collection<String> contents) throws ExportException {
\r
379 ContentTypeAction action = getOrCreate();
\r
380 return action.getLabels(ctx, contents);
\r
385 static class DiscovererImpl implements Discoverer {
\r
386 IConfigurationElement ce;
\r
387 DiscoverAction action;
\r
389 public DiscovererImpl(IConfigurationElement ce) {
\r
394 public String contentTypeId() {
\r
395 return ce.getAttribute("content_type_id");
\r
398 DiscoverAction getOrCreate() throws ExportException {
\r
399 if ( action == null ) {
\r
401 action = (DiscoverAction) ce.createExecutableExtension("discoverAction");
\r
402 } catch (CoreException e) {
\r
403 throw new ExportException( e );
\r
409 // public Read<Collection<String>> discoverRequest(
\r
410 // Collection<String> startLocations) throws ExportException {
\r
411 // return getOrCreate().discoverRequest(startLocations);
\r
415 public String toString() {
\r
417 return "Discoverer, contentTypeId="+contentTypeId()+", class="+getOrCreate().getClass().getCanonicalName();
\r
418 } catch (ExportException e) {
\r
419 return "Discoverer, contentTypeId="+contentTypeId();
\r
424 public Collection<String> discoverContent(ExportContext ctx, Collection<String> startLocations) throws ExportException {
\r
425 return getOrCreate().discoverContent(ctx, startLocations);
\r
430 static class ExporterImpl implements Exporter {
\r
431 IConfigurationElement ce;
\r
432 ExportClass action;
\r
435 public ExporterImpl(IConfigurationElement ce) {
\r
437 String priorityStr = ce.getAttribute("exportPriority");
\r
438 if ( priorityStr!=null ) priority = Integer.valueOf(priorityStr);
\r
441 ExportClass getOrCreate() throws ExportException {
\r
442 if ( action == null ) {
\r
444 action = (ExportClass) ce.createExecutableExtension("exportAction");
\r
445 } catch (CoreException e) {
\r
446 throw new ExportException( e );
\r
453 public String formatId() {
\r
454 return ce.getAttribute("formatId");
\r
458 public String contentTypeId() {
\r
459 return ce.getAttribute("content_type_id");
\r
463 public ExportClass exportAction() throws ExportException {
\r
464 return getOrCreate();
\r
468 public String toString() {
\r
470 return "Exporter, formatId="+formatId()+", contentTypeId="+contentTypeId()+", class="+getOrCreate().getClass().getCanonicalName();
\r
471 } catch (ExportException e) {
\r
472 return "Exporter, formatId="+formatId()+", contentTypeId="+contentTypeId();
\r
477 public int getExportPriority() {
\r
483 static class ImporterImpl implements Importer {
\r
484 IConfigurationElement ce;
\r
486 public ImporterImpl(IConfigurationElement ce) {
\r
491 public String formatId() {
\r
492 return ce.getAttribute("formatId");
\r
496 public String contentTypeId() {
\r
497 return ce.getAttribute("content_type_id");
\r
501 public ImportAction importAction() throws ExportException {
\r
503 return (ImportAction) ce.createExecutableExtension("exportAction");
\r
504 } catch (CoreException e) {
\r
505 throw new ExportException(e);
\r
510 public String toString() {
\r
511 return "Importer, formatId="+formatId()+", contentTypeId="+contentTypeId();
\r
517 static class FormatImpl implements Format {
\r
518 IConfigurationElement ce;
\r
519 FormatClass formatClass;
\r
521 public FormatImpl(IConfigurationElement ce) {
\r
525 FormatClass getOrCreateFormatClass() throws ExportException {
\r
526 if ( formatClass == null ) {
\r
528 formatClass = (FormatClass) ce.createExecutableExtension("formatClass");
\r
529 } catch (CoreException e) {
\r
530 e.printStackTrace();
\r
531 throw new ExportException( e );
\r
534 return formatClass;
\r
538 public String id() {
\r
539 return ce.getAttribute("id");
\r
543 public String label() {
\r
544 return ce.getAttribute("label");
\r
548 public String plural() {
\r
549 return ce.getAttribute("plural");
\r
553 public ImageDescriptor icon() {
\r
555 String _url = ce.getAttribute("icon");
\r
556 URL url = new URL(_url);
\r
557 return ImageDescriptor.createFromURL(url);
\r
558 } catch (MalformedURLException e) {
\r
564 public String fileext() {
\r
565 return ce.getAttribute("fileext");
\r
569 public Class<?> writerClass() throws ClassNotFoundException {
\r
570 String className = ce.getAttribute("writerClass");
\r
571 return Class.forName(className);
\r
575 public Class<?> readerClass() throws ClassNotFoundException {
\r
576 String className = ce.getAttribute("readerClass");
\r
577 return Class.forName(className);
\r
581 public boolean isGroupFormat() {
\r
582 return "true".equals(ce.getAttribute("isGroupFormat"));
\r
586 public boolean isContainerFormat() {
\r
587 return "true".equals(ce.getAttribute("isContainerFormat"));
\r
591 public boolean isAttachable() {
\r
592 return "true".equals(ce.getAttribute("isAttachable"));
\r
596 public boolean mergeGroupFormatDefault() {
\r
597 return "true".equals(ce.getAttribute("mergeGroupDefault"));
\r
601 public boolean isAlwaysPublished() {
\r
602 return "true".equals(ce.getAttribute("isAlwaysPublished"));
\r
606 public boolean isLinkContainer() {
\r
607 return "true".equals(ce.getAttribute("isLinkContainer"));
\r
610 public RecordType options( ExportContext context ) throws ExportException {
\r
611 return getOrCreateFormatClass().options(context);
\r
615 public List<String> validate(ExportContext context, Variant options) throws ExportException {
\r
616 return getOrCreateFormatClass().validate(context, options);
\r
620 public void fillDefaultPrefs( ExportContext ctx, Variant options ) throws ExportException {
\r
621 getOrCreateFormatClass().fillDefaultPrefs( ctx, options );
\r
626 public String toString() {
\r
628 return "Format, id="+id()+", fileext="+fileext()+", label="+label()+", class="+getOrCreateFormatClass().getClass().getCanonicalName();
\r
629 } catch (ExportException e) {
\r
630 return "Format, id="+id()+", fileext="+fileext()+", label="+label();
\r
635 public Object createFile(ExportContext context, File outputFile, Variant options) throws ExportException {
\r
636 return getOrCreateFormatClass().createFile(context, outputFile, options);
\r
640 public Object openFile(ExportContext context, File inputFile, Variant options) throws ExportException {
\r
641 return getOrCreateFormatClass().openFile(context, inputFile, options);
\r
645 public void closeFile(ExportContext context, Object handle) throws ExportException {
\r
646 getOrCreateFormatClass().closeFile(context, handle);
\r
650 public void addAttachment(ExportContext context, Object handle, List<Content> attachments) throws ExportException {
\r
651 getOrCreateFormatClass().addAttachment(context, handle, attachments);
\r
655 public FormatClass formatActions() throws ExportException {
\r
656 return getOrCreateFormatClass();
\r
660 public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {
\r
661 getOrCreateFormatClass().savePref(options, contentScopeNode, workbenchScopeNode);
\r
665 public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {
\r
666 getOrCreateFormatClass().loadPref(options, contentScopeNode, workbenchScopeNode);
\r
671 public static class PublisherImpl implements Publisher {
\r
673 IConfigurationElement ce;
\r
674 PublisherClass publisherClass;
\r
676 public PublisherImpl(IConfigurationElement ce) {
\r
680 PublisherClass getOrCreatePublisherClass() throws ExportException {
\r
681 if ( publisherClass == null ) {
\r
683 publisherClass = (PublisherClass) ce.createExecutableExtension("publisherClass");
\r
684 } catch (CoreException e) {
\r
685 e.printStackTrace();
\r
686 throw new ExportException( e );
\r
689 return publisherClass;
\r
693 public String id() {
\r
694 return ce.getAttribute("id");
\r
698 public String label() {
\r
699 return ce.getAttribute("label");
\r
703 public org.simantics.export.core.intf.PublisherClass publisherClass() throws ExportException {
\r
704 return getOrCreatePublisherClass();
\r
708 public String toString() {
\r
715 public ContentType[] contentTypes() {
\r
716 return contentTypes;
\r
720 public Discoverer[] discoverers() {
\r
721 return discoverers;
\r
725 public Format[] formats() {
\r
730 public Importer[] importers() {
\r
735 public Exporter[] exporters() {
\r
739 public Publisher[] publishers() {
\r
743 Comparator<Exporter> exporterPrioritySorter = new Comparator<Exporter>() {
\r
745 public int compare(Exporter o1, Exporter o2) {
\r
746 return Integer.signum( o2.getExportPriority() - o1.getExportPriority() );
\r