    001/*******************************************************************************
    002 * Copyright (c) 2016 Diamond Light Source Ltd. and others.
    003 * All rights reserved. This program and the accompanying materials
    004 * are made available under the terms of the Eclipse Public License v1.0
    005 * which accompanies this distribution, and is available at
    006 * http://www.eclipse.org/legal/epl-v10.html
    007 *
    008 * Contributors:
    009 *     Diamond Light Source Ltd - initial API and implementation
    010 *******************************************************************************/
    011package org.eclipse.january.metadata;
    012
    013import java.lang.reflect.Method;
    014import java.util.HashMap;
    015import java.util.Map;
    016
    017import org.eclipse.january.MetadataException;
    018import org.eclipse.january.dataset.LazyDatasetBase;
    019import org.eclipse.january.metadata.internal.AxesMetadataImpl;
    020import org.eclipse.january.metadata.internal.DimensionMetadataImpl;
    021import org.eclipse.january.metadata.internal.ErrorMetadataImpl;
    022import org.eclipse.january.metadata.internal.MaskMetadataImpl;
    023import org.eclipse.january.metadata.internal.OriginMetadataImpl;
    024import org.eclipse.january.metadata.internal.PeemMetadataImpl;
    025import org.eclipse.january.metadata.internal.StatisticsMetadataImpl;
    026import org.eclipse.january.metadata.internal.UnitMetadataImpl;
    027
    028public class MetadataFactory {
    029
    030        private MetadataFactory() {
    031        }
    032
    033        static Map<Class<? extends MetadataType>, Class<? extends MetadataType>> metadataClasses = createMap();
    034        private static Map<Class<? extends MetadataType>, Class<? extends MetadataType>> createMap() {
    035                Map<Class<? extends MetadataType>, Class<? extends MetadataType>> map = new HashMap<Class<? extends MetadataType>, Class<? extends MetadataType>>();
    036                map.put(IMetadata.class, Metadata.class);
    037                map.put(ErrorMetadata.class, ErrorMetadataImpl.class);
    038                map.put(AxesMetadata.class, AxesMetadataImpl.class);
    039                map.put(DimensionMetadata.class, DimensionMetadataImpl.class);
    040                map.put(MaskMetadata.class, MaskMetadataImpl.class);
    041                map.put(OriginMetadata.class, OriginMetadataImpl.class);
    042                map.put(PeemMetadata.class, PeemMetadataImpl.class);
    043                map.put(StatisticsMetadata.class, StatisticsMetadataImpl.class);
    044                map.put(UnitMetadata.class, UnitMetadataImpl.class);
    045                return map;
    046        }
    047
    048
    049        /**
    050         * Create a metadata object of given class with given arguments
    051         * @param clazz
    052         * @param arguments these must match the arguments given in the initialize method specified in the class
    053         * @return metadata object or null if type not available
    054         * @throws MetadataException if the class cannot be instantiated, the initialize method does not exist, or
    055         *  the initialize method could not be called successfully
    056         */
    057        public static <T extends MetadataType> T createMetadata(Class<T> clazz, Object... arguments) throws MetadataException {
    058                @SuppressWarnings("unchecked")
    059                Class<T> mdClass = (Class<T>) metadataClasses.get(clazz);
    060                if (mdClass == null) {
    061                        return null;
    062                }
    063
    064                T obj = null;
    065                try {
    066                        obj = mdClass.newInstance();
    067                } catch (Exception e) {
    068                        throw new MetadataException("Could not create metadata object", e);
    069                }
    070
    071                try {
    072                        for (Method m : mdClass.getMethods()) {
    073                                if (m.getName().equals("initialize")) {
    074                                        m.invoke(obj, arguments);
    075                                        return obj;
    076                                }
    077                        }
    078                } catch (Exception e) {
    079                        throw new MetadataException("Could not initialize object", e);
    080                }
    081                throw new MetadataException("Could not find initialize method");
    082        }
    083
    084        /**
    085         * Register metadata class
    086         * @param clazz
    087         */
    088        public static <T extends MetadataType> void registerClass(Class<T> clazz) {
    089                Class<? extends MetadataType> iClass = LazyDatasetBase.findMetadataTypeSubInterfaces(clazz);
    090
    091                metadataClasses.put(iClass, clazz);
    092        }
    093}