package org.simantics.export.core.util; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; import org.simantics.databoard.Accessors; import org.simantics.databoard.Bindings; import org.simantics.databoard.accessor.Accessor; import org.simantics.databoard.accessor.RecordAccessor; import org.simantics.databoard.accessor.UnionAccessor; import org.simantics.databoard.accessor.error.AccessorConstructionException; import org.simantics.databoard.accessor.error.AccessorException; import org.simantics.databoard.accessor.error.ReferenceException; import org.simantics.databoard.accessor.reference.ChildReference; import org.simantics.databoard.accessor.reference.LabelReference; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.type.Component; import org.simantics.databoard.type.UnionType; 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.Exporter; import org.simantics.export.core.intf.Publisher; import org.simantics.export.core.manager.Content; import org.simantics.utils.datastructures.MapList; import org.simantics.utils.strings.AlphanumComparator; public class ExporterUtils { /** * Gets publisher location options from options variant. * * @param ctx * @param publisherId * @param options * @return publisher options or null * @throws ExportException */ public static Variant getPublisherLocationOptions(ExportContext ctx, String publisherId, Variant options) throws ExportException { try { Publisher publisher = ctx.eep.getPublisher(publisherId); Variant locationOptions = options.getComponent( new LabelReference( publisher.label() ) ); return locationOptions; } catch (AccessorConstructionException e) { throw new ExportException( e ); } } /** * Checks if key exists in a preference node * * @param pref * @param key * @return true if key exists */ public static boolean containsKey(Preferences pref, String key) { try { for (String x : pref.keys()) if ( x.equals(key) ) return true; } catch (BackingStoreException e) { e.printStackTrace(); } return false; } /** * Get value of a key, in a preference node. * * @param pref (optional) * @param key key * @return if pref and value exists, the value. */ public static String getPrefString(Preferences pref, String key) { if ( pref == null ) return null; if ( !containsKey(pref, key) ) return null; return pref.get(key, null); } /** * Get value first from pref1, then pref2 * @param pref1 (optional) pririty preference node * @param pref2 (optional) 2nd priority node * @param key * @return possible value */ public static String getPrefString(Preferences pref1, Preferences pref2, String key) { if ( pref1 != null && containsKey(pref1, key) ) return pref1.get(key, null); if ( pref2 != null && containsKey(pref2, key) ) return pref2.get(key, null); return null; } /** * Get value first from pref1, then pref2 * @param pref1 (optional) pririty preference node * @param pref2 (optional) 2nd priority node * @param key * @return possible value */ public static Integer getPrefInteger(Preferences pref1, Preferences pref2, String key) { if ( pref1 != null && containsKey(pref1, key) ) return pref1.getInt(key, -1); if ( pref2 != null && containsKey(pref2, key) ) return pref2.getInt(key, -1); return null; } /** * Get value first from pref1, then pref2 * @param pref1 (optional) pririty preference node * @param pref2 (optional) 2nd priority node * @param key * @return possible value */ public static Boolean getPrefBoolean(Preferences pref1, Preferences pref2, String key) { if ( pref1 != null && containsKey(pref1, key) ) return pref1.getBoolean(key, false); if ( pref2 != null && containsKey(pref2, key) ) return pref2.getBoolean(key, false); return null; } /** * Get value first from pref1, then pref2 * @param pref1 (optional) pririty preference node * @param pref2 (optional) 2nd priority node * @param key * @return possible value */ public static Double getPrefDouble(Preferences pref1, Preferences pref2, String key) { if ( pref1 != null && containsKey(pref1, key) ) return pref1.getDouble(key, 0.0); if ( pref2 != null && containsKey(pref2, key) ) return pref2.getDouble(key, 0.0); return null; } public static void setPrefString(Preferences pref, String key, String value) { if ( pref == null ) return; if ( value == null ) { pref.remove(key); } else { pref.put(key, value); } } public static void setPrefInt(Preferences pref, String key, Integer value) { if ( pref == null ) return; if ( value == null ) { pref.remove(key); } else { pref.putInt(key, value); } } public static void setPrefdouble(Preferences pref, String key, Double value) { if ( pref == null ) return; if ( value == null ) { pref.remove(key); } else { pref.putDouble(key, value); } } /** * Set enum or union value to an accessor, using the string name of the enum value. * If value doesn't exist, false is returned. * If tagName doesn't exist, false is returned. * * @param ra accessor * @param ref child reference * @param tagName (optional) the tag name * @return true if value was set */ public static boolean setUnionValue(Accessor ra, ChildReference ref, String tagName) { if ( tagName == null ) return false; try { UnionAccessor ua = ra.getComponent( ref ); UnionType ut = ua.type(); int tag = ut.getComponentIndex2( tagName ); if ( tag<0 ) return false; Component c = ut.components[tag]; Binding cb = Bindings.getMutableBinding(c.type); Object o = cb.createDefault(); ua.setComponentValue( tag, cb, o); return true; } catch (ReferenceException re) { return false; } catch (AccessorConstructionException e) { e.printStackTrace(); return false; } catch (AccessorException e) { e.printStackTrace(); return false; } catch (BindingException e) { e.printStackTrace(); return false; } } /** * Set enum or union value to an accessor, using the string name of the enum value. * If value doesn't exist, false is returned. * If tagName doesn't exist, false is returned. * * @param ra accessor * @param ref child reference * @param tag the tag number (applied only if >=0) * @return true if value was set */ public static boolean setUnionValue(Accessor ra, ChildReference ref, int tag) { if ( tag<0 ) return false; try { UnionAccessor ua = ra.getComponent( ref ); UnionType ut = ua.type(); Component c = ut.components[tag]; Binding cb = Bindings.getMutableBinding(c.type); Object o = cb.createDefault(); ua.setComponentValue( tag, cb, o); return true; } catch (ReferenceException re) { return false; } catch (AccessorConstructionException e) { e.printStackTrace(); return false; } catch (AccessorException e) { e.printStackTrace(); return false; } catch (BindingException e) { e.printStackTrace(); return false; } } /** * Get union value as a String * * @param ra * @param ref * @return the union value as string or null if error occured */ public static String getUnionValue(Accessor ra, ChildReference ref) { try { UnionAccessor ua = ra.getComponent( ref ); UnionType ut = ua.type(); int tag = ua.getTag(); return ut.components[tag].name; } catch (ReferenceException re) { return null; } catch (AccessorConstructionException e) { e.printStackTrace(); return null; } catch (AccessorException e) { e.printStackTrace(); return null; } } /** * * @param ra * @param ref * @return tag or -1 */ public static int getUnionInt(Accessor ra, ChildReference ref) { try { UnionAccessor ua = ra.getComponent( ref ); int tag = ua.getTag(); return tag; } catch (ReferenceException re) { return -1; } catch (AccessorConstructionException e) { e.printStackTrace(); return -1; } catch (AccessorException e) { e.printStackTrace(); return -1; } } /** * Read string value from an location * * @param location * @param ref * @return the value or null, if did not exist */ public static String getString(Variant location, ChildReference ref) { try { RecordAccessor ra = Accessors.getAccessor(location); return (String) ra.getValue( ref, Bindings.STRING ); } catch (AccessorConstructionException e) { return null; } catch (AccessorException e) { return null; } } public static Boolean getBoolean(Variant location, ChildReference ref) { try { RecordAccessor ra = Accessors.getAccessor(location); return (Boolean) ra.getValue( ref, Bindings.BOOLEAN ); } catch (AccessorConstructionException e) { return null; } catch (AccessorException e) { return null; } } public static Comparator createExportPriorityComparator( final ExportExtensionPoint eep ) { return new Comparator() { @Override public int compare(Content c1, Content c2) { int p1 = Integer.MAX_VALUE; for (Exporter e : eep.getExporters(c1.formatId, c1.contentTypeId)) p1 = Math.min(p1, e.getExportPriority()); int p2 = Integer.MAX_VALUE; for (Exporter e : eep.getExporters(c2.formatId, c2.contentTypeId)) p2 = Math.min(p2, e.getExportPriority()); return Integer.signum( p1 - p2 ); } }; } /** * Takes a maplist of contents as input and filters out all that matches * to the given uri. * * @param map * @param contentUri * @return map with contents of given Uri. */ public static MapList filterByUri(MapList map, String contentUri) { if ( map == null ) return null; MapList result = new MapList(); for ( Content key : map.getKeys() ) { if ( key.url.equals(contentUri) ) { result.addAll(key, map.getValuesUnsafe(key)); } } return result; } public static MapList toStringMap(MapList map) { if ( map == null ) return null; MapList result = new MapList(); for ( Content key : map.getKeys() ) { result.addAll(key.url, map.getValuesUnsafe(key)); } return result; } public static List filterContents(Collection contents, String contentTypeId, String formatId) { if ( contents==null ) return null; List result = new ArrayList(contents.size()); for ( Content content : contents ) { if ( contentTypeId!=null && !content.contentTypeId.equals(contentTypeId) ) continue; if ( formatId!=null && !content.formatId.equals(formatId) ) continue; result.add( content ); } return result; } public static List toUris(Collection contents) { List result = new ArrayList(contents.size()); for ( Content content : contents ) result.add( content.url ); return result; } public static Comparator CONTENT_COMPARATOR = new Comparator() { @Override public int compare(Content o1, Content o2) { int c = AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(o1.url, o2.url); if (c != 0) return c; c = AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(o1.formatId, o2.formatId); if (c != 0) return c; return 0; } }; public static List sortContent(List content) { Collections.sort(content, CONTENT_COMPARATOR); return content; } public static List sortedContent(List content) { ArrayList sorted = new ArrayList(content); sortContent(sorted); return sorted; } }