/* * Copyright (C) 2013 Serdar * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.fub.maps.project.detector.utils; import de.fub.maps.project.detector.filetype.DetectorDataObject; import de.fub.maps.project.detector.model.Detector; import de.fub.maps.project.detector.model.inference.AbstractInferenceModel; import de.fub.maps.project.detector.model.inference.processhandler.InferenceModelProcessHandler; import de.fub.maps.project.detector.model.xmls.DetectorDescriptor; import de.fub.maps.project.detector.model.xmls.InferenceModelDescriptor; import de.fub.maps.project.detector.model.xmls.ProcessHandlerDescriptor; import de.fub.maps.project.detector.model.xmls.Property; import de.fub.maps.project.utils.MapsProjectUtils; import de.fub.utilsmodule.xml.jax.JAXBUtil; import java.awt.Color; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.Preferences; import javax.xml.bind.JAXBException; import org.netbeans.api.project.Project; import org.netbeans.api.project.ui.OpenProjects; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; import org.openide.util.RequestProcessor; /** * * @author Serdar */ public class DetectorUtils { private static final Object DETECTOR_FILE_OPERATION_MUTEX = new Object(); private static final Logger LOG = Logger.getLogger(DetectorUtils.class.getName()); private static RequestProcessor requestProcessor; public static <T> T createInstance(Class<T> clazz, String className) { return createInstance(clazz, className, (Object[]) null); } @SuppressWarnings("unchecked") public static <T> T createInstance(Class<T> clazz, String className, Object... arguments) { T instance = null; try { ClassLoader classLoader = Lookup.getDefault().lookup(ClassLoader.class); Class<?> forName = classLoader.loadClass(className); Class<T> cl = (Class<T>) forName; if (arguments == null || arguments.length == 0) { instance = cl.newInstance(); } else { ArrayList<Class<?>> argumentTypes = new ArrayList<Class<?>>(); for (Object object : arguments) { argumentTypes.add(object.getClass()); } Constructor<T> constructor = null; while (cl != null && instance == null) { try { constructor = cl.getConstructor(argumentTypes.toArray(new Class[argumentTypes.size()])); instance = constructor.newInstance(arguments); } catch (NoSuchMethodException ex) { cl = (Class<T>) cl.getSuperclass(); } } } } catch (InstantiationException ex) { Exceptions.printStackTrace(ex); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (ClassNotFoundException ex) { Lookup.Result<T> lookupResult = Lookup.getDefault().lookupResult(clazz); for (T task : lookupResult.allInstances()) { Class<T> cl = (Class<T>) task.getClass(); if (task.getClass().getName().equals(className)) { try { if (arguments == null || arguments.length == 0) { instance = cl.newInstance(); } else { ArrayList<Class<?>> argumentTypes = new ArrayList<Class<?>>(); for (Object object : arguments) { argumentTypes.add(object.getClass()); } Constructor<T> constructor = null; while (cl != null && instance == null) { try { constructor = cl.getConstructor(argumentTypes.toArray(new Class[argumentTypes.size()])); instance = constructor.newInstance(arguments); } catch (NoSuchMethodException ex1) { cl = (Class<T>) cl.getSuperclass(); } catch (IllegalArgumentException ex1) { Exceptions.printStackTrace(ex1); } catch (InvocationTargetException ex1) { Exceptions.printStackTrace(ex1); } } } } catch (InstantiationException ex1) { Exceptions.printStackTrace(ex1); } catch (IllegalAccessException ex1) { Exceptions.printStackTrace(ex1); } } } } catch (SecurityException ex) { Exceptions.printStackTrace(ex); } catch (IllegalArgumentException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } return instance; } @SuppressWarnings({"unchecked"}) public static <T> T getValue(Class<T> clazz, Property property) { T instance = null; if (clazz.getName().equals(Boolean.class.getName())) { instance = (T) Boolean.valueOf(property.getValue()); } else if (clazz.getName().equals(Double.class.getName())) { instance = (T) Double.valueOf(property.getValue()); } else if (clazz.getName().equals(Integer.class.getName())) { instance = (T) Integer.valueOf(property.getValue()); } else if (clazz.getName().equals(String.class.getName())) { instance = (T) property.getValue(); } else if (clazz.getName().equals(Color.class.getName())) { instance = (T) new Color(Integer.parseInt(property.getValue(), 16)); } else if (clazz.getName().equals(Long.class.getName())) { instance = (T) Long.valueOf(property.getValue()); } else if (clazz.isEnum()) { T[] enumConstants = clazz.getEnumConstants(); for (T enu : enumConstants) { if (enu.toString().equals(property.getValue())) { instance = enu; break; } } } else { try { Constructor<T> constructor = clazz.getDeclaredConstructor(String.class); instance = constructor.newInstance(property.getValue()); } catch (NoSuchMethodException ex) { Exceptions.printStackTrace(ex); } catch (SecurityException ex) { Exceptions.printStackTrace(ex); } catch (InstantiationException ex) { Exceptions.printStackTrace(ex); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (IllegalArgumentException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } return instance; } @NbBundle.Messages({ "# {0} - filepath", "CLT_File_not_found=Couldn't find associated xml process descriptor file at path: {0}"}) @SuppressWarnings("unchecked") public static <T> T getXmlDescriptor(Class<T> destClass, Class<?> sourceClass) throws IOException { T descriptor = null; String filePatn = MessageFormat.format("/{0}.xml", sourceClass.getName().replaceAll("\\.", "/")); InputStream resourceAsStream = sourceClass.getResourceAsStream(filePatn); if (resourceAsStream != null) { try { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(destClass); javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller(); descriptor = (T) unmarshaller.unmarshal(resourceAsStream); //NOI18N } catch (javax.xml.bind.JAXBException ex) { throw new IOException(ex); } finally { resourceAsStream.close(); } } else { throw new FileNotFoundException(Bundle.CLT_File_not_found(filePatn)); } return descriptor; } public static ProcessHandlerDescriptor createProcessHandler(Class<? extends InferenceModelProcessHandler> aClass) { ProcessHandlerDescriptor descriptor = null; return descriptor; } @SuppressWarnings("unchecked") public static InferenceModelProcessHandler createProcessHandler(ProcessHandlerDescriptor descriptor, Detector detector) { InferenceModelProcessHandler model = null; try { if (descriptor != null && detector != null) { Class<?> clazz = Class.forName(descriptor.getJavaType()); if (AbstractInferenceModel.class .isAssignableFrom(clazz)) { Class<? extends InferenceModelProcessHandler> abstractInferenceModel = (Class<? extends InferenceModelProcessHandler>) clazz; Constructor<? extends InferenceModelProcessHandler> constructor = abstractInferenceModel.getConstructor(Detector.class); model = constructor.newInstance(detector); } } } catch (ClassNotFoundException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } catch (NoSuchMethodException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } catch (SecurityException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } catch (InstantiationException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } catch (IllegalAccessException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } catch (IllegalArgumentException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); // Exceptions.printStackTrace(ex); } return model; } @SuppressWarnings("unchecked") public static AbstractInferenceModel createInferenceModel(InferenceModelDescriptor descriptor, Detector detector) { AbstractInferenceModel model = null; try { if (descriptor != null && detector != null) { Class<?> clazz = Class.forName(descriptor.getJavaType()); if (AbstractInferenceModel.class .isAssignableFrom(clazz)) { Class<? extends AbstractInferenceModel> abstractInferenceModel = (Class<? extends AbstractInferenceModel>) clazz; Constructor<? extends AbstractInferenceModel> constructor = abstractInferenceModel.getConstructor(Detector.class); model = constructor.newInstance(detector); } } } catch (ClassNotFoundException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } catch (NoSuchMethodException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } catch (SecurityException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } catch (InstantiationException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } catch (IllegalAccessException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } catch (IllegalArgumentException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } catch (InvocationTargetException ex) { LOG.log(Level.FINE, ex.getMessage(), ex); } return model; } public static synchronized Project findProject(FileObject fileObject) { return MapsProjectUtils.findProject(fileObject); } public static FileObject findFileObject(FileObject detectorFileObject, String relativePathInProject) { FileObject fileObject = null; if (detectorFileObject != null && detectorFileObject.getParent() != null) { try { Project project = findProject(detectorFileObject); if (project != null) { fileObject = project.getProjectDirectory().getFileObject(relativePathInProject); } } catch (IllegalArgumentException ex) { Exceptions.printStackTrace(ex); } } else { for (Project project : OpenProjects.getDefault().getOpenProjects()) { fileObject = project.getProjectDirectory().getFileObject(relativePathInProject); if (fileObject != null) { break; } } } return fileObject; } /** * Method to override the original detector description with the copy * instance. * * @param original - the detector instance that will be over written with * the copy instance. * @param copy - detector copy instance. */ public static void mergeDetector(Detector original, Detector copy) { saveDetector(original.getDataObject(), copy.getDetectorDescriptor()); } public static void saveDetector(DetectorDataObject dataObject) throws JAXBException, IOException { saveDetector(dataObject, dataObject.getDetectorDescriptor()); } public static void saveDetector(final DataObject dataObject, final DetectorDescriptor descriptor) { saveDetector(dataObject.getPrimaryFile(), descriptor); } public static void saveDetector(final FileObject fileObject, final DetectorDescriptor descriptor) { FileUtil.runAtomicAction(new Runnable() { @Override public void run() { try { JAXBUtil.saveDetector(fileObject, descriptor); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } } }); } public static DetectorDescriptor getDetectorDescriptor(DataObject dataObject) throws JAXBException, IOException { return getDetectorDescriptor(dataObject.getPrimaryFile()); } public static DetectorDescriptor getDetectorDescriptor(FileObject fileObject) throws JAXBException, IOException { return JAXBUtil.createDescriptor(DetectorDescriptor.class, fileObject); } public static Detector copyInstance(Detector detector) throws DetectorCopyException { Detector copy = null; DetectorDescriptor detectorDescriptor = detector.getDetectorDescriptor(); try { if (detectorDescriptor == null) { throw new DetectorCopyException("descriptor of detector is null!"); } File copyFile = File.createTempFile("detector", ".dec"); FileObject fileObject = FileUtil.toFileObject(copyFile); saveDetector(fileObject, detectorDescriptor); DataObject dataObject = DataObject.find(fileObject); copy = dataObject.getNodeDelegate().getLookup().lookup(Detector.class); if (copy == null) { throw new DetectorCopyException(MessageFormat.format("Failed to create a copy of detector {0}", detector.getDetectorDescriptor().getName())); } } catch (IOException ex) { throw new DetectorCopyException(ex.getMessage(), ex); } return copy; } public static FileObject getDatasourceFileObject() { FileObject fileObject = null; ClassLoader classLoader = Lookup.getDefault().lookup(ClassLoader.class); try { Preferences preferences = NbPreferences.forModule(classLoader.loadClass("de.fub.mapsforge.project.datasource.MapsForgeDatasourceNodeFactory")); String filePath = preferences.get("GPX Datasource", null); if (filePath != null) { File file = new File(filePath); fileObject = FileUtil.toFileObject(file); } } catch (ClassNotFoundException ex) { Exceptions.printStackTrace(ex); } return fileObject; } public static class DetectorCopyException extends Exception { private static final long serialVersionUID = 1L; public DetectorCopyException() { } public DetectorCopyException(String message) { super(message); } public DetectorCopyException(String message, Throwable cause) { super(message, cause); } public DetectorCopyException(Throwable cause) { super(cause); } public DetectorCopyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } public static RequestProcessor getDefaultRequestProcessor() { if (requestProcessor == null) { requestProcessor = new RequestProcessor(Detector.class.getName(), Runtime.getRuntime().availableProcessors() * 2); } return requestProcessor; } }