package org.simantics.export.core.impl; import java.io.File; import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.osgi.service.prefs.Preferences; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.type.RecordType; import org.simantics.export.core.ExportContext; import org.simantics.export.core.ExportExtensionPoint; import org.simantics.export.core.error.ExportException; import org.simantics.export.core.intf.ContentType; import org.simantics.export.core.intf.ContentTypeAction; import org.simantics.export.core.intf.DiscoverAction; import org.simantics.export.core.intf.Discoverer; import org.simantics.export.core.intf.ExportClass; import org.simantics.export.core.intf.Exporter; import org.simantics.export.core.intf.Format; import org.simantics.export.core.intf.FormatClass; import org.simantics.export.core.intf.IconResolver; import org.simantics.export.core.intf.ImportAction; import org.simantics.export.core.intf.Importer; import org.simantics.export.core.intf.Publisher; import org.simantics.export.core.intf.PublisherClass; import org.simantics.export.core.manager.Content; import org.simantics.utils.datastructures.ToStringComparator; /** * Light-weight registry implementation to export extension point. * * @author toni.kalajainen@semantum.fi */ public class ExportExtensionPointImpl implements ExportExtensionPoint { public static final String EP = "org.simantics.export.core.export"; Importer[] importers = createImporters(); Exporter[] exporters = createExporters(); Format[] formats = createFormats(); ContentType[] contentTypes = createContentTypes(); Discoverer[] discoverers = createDiscoverers(); Publisher[] publishers = createPublishers(); public ExportExtensionPointImpl() {} public Discoverer[] getDiscoverers(String contentTypeId) { int count = 0; for ( Discoverer discoverer : discoverers ) { if ( contentTypeId.equals( discoverer.contentTypeId() ) ) count++; } Discoverer[] result = new Discoverer[ count ]; int i = 0; for ( Discoverer discoverer : discoverers ) { if ( contentTypeId.equals( discoverer.contentTypeId() ) ) { result[ i++ ] = discoverer; } } return result; } public Format getFormat(String formatId) { for ( Format format : formats ) { if ( formatId.equals( format.id() ) ) return format; } return null; } @Override public Format getFormatByExt(String fileExt) { for ( Format format : formats ) { if ( fileExt.equals( format.fileext() ) ) return format; } return null; } public ContentType getContentType(String contentTypeId) //throws ExportException { for ( ContentType contentType : contentTypes ) { if ( contentTypeId.equals( contentType.id() ) ) return contentType; } //throw new ExportException("ContentType "+contentTypeId+" does not exist"); return null; } public Importer getImporter(String formatId) //throws ExportException { for ( Importer importer : importers ) { if ( formatId.equals( importer.formatId() ) ) return importer; } //throw new ExportException("Importer "+formatId+" does not exist"); return null; } public Exporter[] getExporters(String formatId, String contentTypeId) { int count = 0; for ( Exporter exporter : exporters ) { if ( exporter.formatId().equals(formatId) && exporter.contentTypeId().equals(contentTypeId) ) count++; } Exporter[] result = new Exporter[ count ]; int index = 0; for ( Exporter exporter : exporters ) { if ( formatId.equals( exporter.formatId() ) && contentTypeId.equals( exporter.contentTypeId() ) ) { result[ index++ ] = exporter; } } return result; } public Exporter[] getExportersForContentType(String contentTypeId) //throws ExportException { int count = 0; for ( Exporter exporter : exporters ) { if ( contentTypeId.equals( exporter.contentTypeId() ) ) count++; } Exporter[] result = new Exporter[ count ]; int i = 0; for ( Exporter exporter : exporters ) { if ( contentTypeId.equals( exporter.contentTypeId() ) ) { result[ i++ ] = exporter; } } Arrays.sort(result, exporterPrioritySorter); return result; } public Exporter[] getExportersForFormat(String formatId) { int count = 0; for ( Exporter exporter : exporters ) { if ( formatId.equals( exporter.formatId() ) ) count++; } Exporter[] result = new Exporter[ count ]; int i = 0; for ( Exporter exporter : exporters ) { if ( formatId.equals( exporter.formatId() ) ) { result[ i++ ] = exporter; } } Arrays.sort(result, exporterPrioritySorter); return result; } public Publisher getPublisher(String publisherId) { for ( Publisher publisher : publishers ) { if ( publisherId.equals( publisher.id() ) ) return publisher; } return null; }; public int getPublisherIndex(String publisherId) { for (int i=0; i resolverCache = null; boolean invalidIconResolver = false; public ContentTypeImpl(IConfigurationElement ce) { this.ce = ce; } ContentTypeAction getOrCreate() throws ExportException { if ( action == null ) { try { String value = ce.getAttribute("contentTypeAction"); if ( value == null ) return new DefaultContentTypeAction(); action = (ContentTypeAction) ce.createExecutableExtension("contentTypeAction"); } catch (CoreException e) { throw new ExportException( e ); } } return action; } @Override public String id() { return ce.getAttribute("id"); } @Override public String label() { return ce.getAttribute("label"); } @Override public String plural() { return ce.getAttribute("plural"); } public ImageDescriptor icon(String contentUri) { if (!invalidIconResolver && ce.getAttribute("iconResolver") != null) { try { IconResolver resolver = resolverCache != null ? resolverCache.get() : null; if (resolver == null) { resolver = (IconResolver) ce.createExecutableExtension("iconResolver"); resolverCache = new WeakReference(resolver); } return resolver.get(contentUri); } catch (CoreException e) { // Invalid iconResolver, could not instantiate. // Don't try to resolve it anymore if it fails once. invalidIconResolver = true; return null; } } return icon(); } @Override public ImageDescriptor icon() { try { String _url = ce.getAttribute("icon"); URL url = new URL(_url); return ImageDescriptor.createFromURL(url); } catch (MalformedURLException e) { return null; } } @Override public boolean isModel() { return "true".equalsIgnoreCase(ce.getAttribute("model")); } @Override public String toString() { return "ContentType, id="+id()+", label="+label(); } @Override public Map getLabels(ExportContext ctx, Collection contents) throws ExportException { ContentTypeAction action = getOrCreate(); return action.getLabels(ctx, contents); } } static class DiscovererImpl implements Discoverer { IConfigurationElement ce; DiscoverAction action; public DiscovererImpl(IConfigurationElement ce) { this.ce = ce; } @Override public String contentTypeId() { return ce.getAttribute("content_type_id"); } DiscoverAction getOrCreate() throws ExportException { if ( action == null ) { try { action = (DiscoverAction) ce.createExecutableExtension("discoverAction"); } catch (CoreException e) { throw new ExportException( e ); } } return action; } // public Read> discoverRequest( // Collection startLocations) throws ExportException { // return getOrCreate().discoverRequest(startLocations); // } @Override public String toString() { try { return "Discoverer, contentTypeId="+contentTypeId()+", class="+getOrCreate().getClass().getCanonicalName(); } catch (ExportException e) { return "Discoverer, contentTypeId="+contentTypeId(); } } @Override public Collection discoverContent(ExportContext ctx, Collection startLocations) throws ExportException { return getOrCreate().discoverContent(ctx, startLocations); } } static class ExporterImpl implements Exporter { IConfigurationElement ce; ExportClass action; int priority = 0; public ExporterImpl(IConfigurationElement ce) { this.ce = ce; String priorityStr = ce.getAttribute("exportPriority"); if ( priorityStr!=null ) priority = Integer.valueOf(priorityStr); } ExportClass getOrCreate() throws ExportException { if ( action == null ) { try { action = (ExportClass) ce.createExecutableExtension("exportAction"); } catch (CoreException e) { throw new ExportException( e ); } } return action; } @Override public String formatId() { return ce.getAttribute("formatId"); } @Override public String contentTypeId() { return ce.getAttribute("content_type_id"); } @Override public ExportClass exportAction() throws ExportException { return getOrCreate(); } @Override public String toString() { try { return "Exporter, formatId="+formatId()+", contentTypeId="+contentTypeId()+", class="+getOrCreate().getClass().getCanonicalName(); } catch (ExportException e) { return "Exporter, formatId="+formatId()+", contentTypeId="+contentTypeId(); } } @Override public int getExportPriority() { return priority; } } static class ImporterImpl implements Importer { IConfigurationElement ce; public ImporterImpl(IConfigurationElement ce) { this.ce = ce; } @Override public String formatId() { return ce.getAttribute("formatId"); } @Override public String contentTypeId() { return ce.getAttribute("content_type_id"); } @Override public ImportAction importAction() throws ExportException { try { return (ImportAction) ce.createExecutableExtension("exportAction"); } catch (CoreException e) { throw new ExportException(e); } } @Override public String toString() { return "Importer, formatId="+formatId()+", contentTypeId="+contentTypeId(); } } static class FormatImpl implements Format { IConfigurationElement ce; FormatClass formatClass; public FormatImpl(IConfigurationElement ce) { this.ce = ce; } FormatClass getOrCreateFormatClass() throws ExportException { if ( formatClass == null ) { try { formatClass = (FormatClass) ce.createExecutableExtension("formatClass"); } catch (CoreException e) { e.printStackTrace(); throw new ExportException( e ); } } return formatClass; } @Override public String id() { return ce.getAttribute("id"); } @Override public String label() { return ce.getAttribute("label"); } @Override public String plural() { return ce.getAttribute("plural"); } @Override public ImageDescriptor icon() { try { String _url = ce.getAttribute("icon"); URL url = new URL(_url); return ImageDescriptor.createFromURL(url); } catch (MalformedURLException e) { return null; } } @Override public String fileext() { return ce.getAttribute("fileext"); } @Override public Class writerClass() throws ClassNotFoundException { String className = ce.getAttribute("writerClass"); return Class.forName(className); } @Override public Class readerClass() throws ClassNotFoundException { String className = ce.getAttribute("readerClass"); return Class.forName(className); } @Override public boolean isGroupFormat() { return "true".equals(ce.getAttribute("isGroupFormat")); } @Override public boolean isContainerFormat() { return "true".equals(ce.getAttribute("isContainerFormat")); } @Override public boolean isAttachable() { return "true".equals(ce.getAttribute("isAttachable")); } @Override public boolean mergeGroupFormatDefault() { return "true".equals(ce.getAttribute("mergeGroupDefault")); } @Override public boolean isAlwaysPublished() { return "true".equals(ce.getAttribute("isAlwaysPublished")); } @Override public boolean isLinkContainer() { return "true".equals(ce.getAttribute("isLinkContainer")); } @Override public RecordType options( ExportContext context ) throws ExportException { return getOrCreateFormatClass().options(context); } @Override public List validate(ExportContext context, Variant options) throws ExportException { return getOrCreateFormatClass().validate(context, options); } @Override public void fillDefaultPrefs( ExportContext ctx, Variant options ) throws ExportException { getOrCreateFormatClass().fillDefaultPrefs( ctx, options ); } @Override public String toString() { try { return "Format, id="+id()+", fileext="+fileext()+", label="+label()+", class="+getOrCreateFormatClass().getClass().getCanonicalName(); } catch (ExportException e) { return "Format, id="+id()+", fileext="+fileext()+", label="+label(); } } @Override public Object createFile(ExportContext context, File outputFile, Variant options) throws ExportException { return getOrCreateFormatClass().createFile(context, outputFile, options); } @Override public Object openFile(ExportContext context, File inputFile, Variant options) throws ExportException { return getOrCreateFormatClass().openFile(context, inputFile, options); } @Override public void closeFile(ExportContext context, Object handle) throws ExportException { getOrCreateFormatClass().closeFile(context, handle); } @Override public void addAttachment(ExportContext context, Object handle, List attachments) throws ExportException { getOrCreateFormatClass().addAttachment(context, handle, attachments); } @Override public FormatClass formatActions() throws ExportException { return getOrCreateFormatClass(); } @Override public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException { getOrCreateFormatClass().savePref(options, contentScopeNode, workbenchScopeNode); } @Override public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException { getOrCreateFormatClass().loadPref(options, contentScopeNode, workbenchScopeNode); } } public static class PublisherImpl implements Publisher { IConfigurationElement ce; PublisherClass publisherClass; public PublisherImpl(IConfigurationElement ce) { this.ce = ce; } PublisherClass getOrCreatePublisherClass() throws ExportException { if ( publisherClass == null ) { try { publisherClass = (PublisherClass) ce.createExecutableExtension("publisherClass"); } catch (CoreException e) { e.printStackTrace(); throw new ExportException( e ); } } return publisherClass; } @Override public String id() { return ce.getAttribute("id"); } @Override public String label() { return ce.getAttribute("label"); } @Override public org.simantics.export.core.intf.PublisherClass publisherClass() throws ExportException { return getOrCreatePublisherClass(); } @Override public String toString() { return label(); } } @Override public ContentType[] contentTypes() { return contentTypes; } @Override public Discoverer[] discoverers() { return discoverers; } @Override public Format[] formats() { return formats; } @Override public Importer[] importers() { return importers; } @Override public Exporter[] exporters() { return exporters; } public Publisher[] publishers() { return publishers; }; Comparator exporterPrioritySorter = new Comparator() { @Override public int compare(Exporter o1, Exporter o2) { return Integer.signum( o2.getExportPriority() - o1.getExportPriority() ); } }; }