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