/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package au.gov.ga.earthsci.bookmark; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.Creatable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import au.gov.ga.earthsci.bookmark.model.IBookmarkProperty; import au.gov.ga.earthsci.bookmark.properties.PlaceholderBookmarkProperty; import au.gov.ga.earthsci.bookmark.properties.PlaceholderBookmarkPropertyExporter; import au.gov.ga.earthsci.common.util.ExtensionRegistryUtil; import au.gov.ga.earthsci.common.util.ExtensionRegistryUtil.Callback; import au.gov.ga.earthsci.common.util.Validate; /** * A factory class that uses registered {@link IBookmarkPropertyCreator}s to * instantiate {@link IBookmarkProperty} instances * * @author James Navin (james.navin@ga.gov.au) */ @Creatable @Singleton public class BookmarkPropertyFactory { private static final String CREATORS_EXTENSION_POINT_ID = "au.gov.ga.earthsci.bookmark.creators"; //$NON-NLS-1$ private static final String EXPORTERS_EXTENSION_POINT_ID = "au.gov.ga.earthsci.bookmark.exporters"; //$NON-NLS-1$ private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$ private static Logger logger = LoggerFactory.getLogger(BookmarkPropertyFactory.class); private static Map<String, IBookmarkPropertyCreator> creators = new ConcurrentHashMap<String, IBookmarkPropertyCreator>(); private static Map<String, IBookmarkPropertyExporter> exporters = new ConcurrentHashMap<String, IBookmarkPropertyExporter>(); static { registerExporter(new PlaceholderBookmarkPropertyExporter()); } /** * Create and return a new property of the given type using the given XML. * * @param type * The type of property to create * @param root * The root of the XML to use for creating the property * * @return A new bookmark property of the given type, created from the given * context */ public static IBookmarkProperty createProperty(String type, Element root) { if (type == null) { return null; } IBookmarkPropertyCreator propertyCreator = creators.get(type); if (propertyCreator == null) { logger.debug("No bookmark property creator found for property type {}", type); //$NON-NLS-1$ return new PlaceholderBookmarkProperty(root); } return propertyCreator.createFromXML(type, root); } /** * Create and return a new property of the given type using the current * world state. * * @param type * The type of property to create * * @return A new bookmark property of the given type, created from the * current world state */ public static IBookmarkProperty createProperty(String type) { if (type == null) { return null; } IBookmarkPropertyCreator propertyCreator = creators.get(type); if (propertyCreator == null) { return null; } return propertyCreator.createFromCurrentState(type); } /** * Export the given property to a map which can be used to persist and/or * re-create the property using {@link #createProperty(String, Map)} * * @param property * The property to export * * @return A map containing the exported information from the given * property, or <code>null</code> if it cannot be exported. */ public static void exportProperty(IBookmarkProperty property, Element parent) { if (property == null) { return; } Validate.notNull(parent, "A parent element is required"); //$NON-NLS-1$ IBookmarkPropertyExporter exporter = exporters.get(property.getType()); if (exporter == null) { return; } exporter.exportToXML(property, parent); } /** * Load the bookmark property creators and exporters from the extension * registry */ @Inject public static void loadFromExtensions(IEclipseContext context) { loadCreatorsFromExtensions(context); loadExportersFromExtensions(context); } private static void loadCreatorsFromExtensions(IEclipseContext context) { logger.debug("Registering bookmark property creators"); //$NON-NLS-1$ try { ExtensionRegistryUtil.createFromExtension(CREATORS_EXTENSION_POINT_ID, CLASS_ATTRIBUTE, IBookmarkPropertyCreator.class, context, new Callback<IBookmarkPropertyCreator>() { @Override public void run(IBookmarkPropertyCreator creator, IConfigurationElement element, IEclipseContext context) { registerCreator(creator); } }); } catch (CoreException e) { logger.error("Exception occurred while loading creator from extension", e); //$NON-NLS-1$ } } private static void loadExportersFromExtensions(IEclipseContext context) { logger.debug("Registering bookmark property exporters"); //$NON-NLS-1$ try { ExtensionRegistryUtil.createFromExtension(EXPORTERS_EXTENSION_POINT_ID, CLASS_ATTRIBUTE, IBookmarkPropertyExporter.class, context, new Callback<IBookmarkPropertyExporter>() { @Override public void run(IBookmarkPropertyExporter exporter, IConfigurationElement element, IEclipseContext context) { registerExporter(exporter); } }); } catch (CoreException e) { logger.error("Exception occurred while loading exporters from extension", e); //$NON-NLS-1$ } } /** * Register the given bookmark property creator with this factory */ public static void registerCreator(IBookmarkPropertyCreator creator) { if (creator == null) { return; } for (String type : creator.getSupportedTypes()) { creators.put(type, creator); } logger.debug("Registered bookmark property creator: {}", creator.getClass()); //$NON-NLS-1$ } /** * Register the given bookmark property exporter with this factory */ public static void registerExporter(IBookmarkPropertyExporter exporter) { if (exporter == null) { return; } for (String type : exporter.getSupportedTypes()) { exporters.put(type, exporter); } logger.debug("Registered bookmark property exporter: {}", exporter.getClass()); //$NON-NLS-1$ } /** * @return The list of known property types which have creators registered * in this factory */ public static String[] getKnownPropertyTypes() { return creators.keySet().toArray(new String[creators.size()]); } /** * @return An instance of every known property with the current world state */ public static IBookmarkProperty[] createKnownProperties() { List<IBookmarkProperty> result = new ArrayList<IBookmarkProperty>(); for (String type : getKnownPropertyTypes()) { result.add(createProperty(type)); } return result.toArray(new IBookmarkProperty[result.size()]); } }