/* * 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.filetype; import de.fub.maps.project.detector.factories.nodes.DetectorNode; import de.fub.maps.project.detector.model.Detector; import de.fub.maps.project.detector.model.xmls.DataSets; import de.fub.maps.project.detector.model.xmls.DetectorDescriptor; import de.fub.maps.project.detector.utils.DetectorUtils; import de.fub.utilsmodule.actions.SaveAsTemplateAction; import java.io.IOException; import java.io.StringWriter; import java.text.MessageFormat; import javax.swing.JComponent; import javax.swing.event.ChangeListener; import javax.swing.text.BadLocationException; import javax.swing.text.StyledDocument; import javax.xml.bind.JAXBException; import org.netbeans.core.spi.multiview.MultiViewElement; import org.netbeans.core.spi.multiview.text.MultiViewEditorElement; import org.netbeans.spi.xml.cookies.CheckXMLSupport; import org.netbeans.spi.xml.cookies.DataObjectAdapters; import org.netbeans.spi.xml.cookies.ValidateXMLSupport; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionReferences; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.filesystems.MIMEResolver; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectExistsException; import org.openide.loaders.MultiDataObject; import org.openide.loaders.MultiFileLoader; import org.openide.nodes.Node; import org.openide.text.DataEditorSupport; import org.openide.util.ChangeSupport; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.Lookups; import org.openide.util.lookup.ProxyLookup; import org.openide.windows.TopComponent; import org.xml.sax.InputSource; @Messages({ "LBL_Detector_LOADER=Files of Detector" }) @MIMEResolver.ExtensionRegistration( displayName = "#LBL_Detector_LOADER", mimeType = "text/detector+xml", extension = {"dec", "Dec", "DEC"}) @MIMEResolver.NamespaceRegistration( displayName = "#LBL_Detector_LOADER", checkedExtension = {"dec", "Dec", "DEC"}, mimeType = "text/detector+xml", elementNS = {"http://inf.fu-berlin.de/mapsforge/detector/schema"}, elementName = "detector") @DataObject.Registration( mimeType = "text/detector+xml", iconBase = "de/fub/maps/project/detector/filetype/detector.png", displayName = "#LBL_Detector_LOADER", position = 300) @ActionReferences({ @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID(category = "System", id = "org.openide.actions.OpenAction"), position = 100, separatorAfter = 200), @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID(category = "Edit", id = "org.openide.actions.CutAction"), position = 300), @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"), position = 400, separatorAfter = 500), @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"), position = 600), @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID( category = "System", id = "de.fub.utilsmodule.actions.SaveAsTemplateAction"), position = 900), @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"), position = 1100, separatorAfter = 1200), // @ActionReference( // path = "Loaders/text/detector+xml/Actions", // id = // @ActionID(category = "System", id = "org.openide.actions.ToolsAction"), // position = 1300), @ActionReference( path = "Loaders/text/detector+xml/Actions", id = @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"), position = 1400) }) public class DetectorDataObject extends MultiDataObject { private static final long serialVersionUID = 1L; private transient Node delegateNode = null; private transient final ChangeSupport cs = new ChangeSupport(this); private transient DetectorDescriptor detectorDescriptor = null; private transient final FileChangeAdapter fileChangeListener = new FileChangeAdapterImpl(); public DetectorDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { super(pf, loader); registerEditor("text/detector+xml", true); InputSource inputSource = DataObjectAdapters.inputSource(DetectorDataObject.this); CheckXMLSupport checkXMLSupport = new CheckXMLSupport(inputSource); ValidateXMLSupport validateXMLSupport = new ValidateXMLSupport(inputSource); getCookieSet().add(new SaveAsTamplateHandlerImpl()); getCookieSet().add(checkXMLSupport); getCookieSet().add(validateXMLSupport); pf.addFileChangeListener(fileChangeListener); } @Override protected int associateLookup() { return 1; } @Override protected Node createNodeDelegate() { if (delegateNode == null) { Detector detector = new Detector(this); getCookieSet().add(detector); DetectorDescriptor detectorDescr = detector.getDetectorDescriptor(); if (detectorDescr != null) { delegateNode = new DetectorNode(detector); } else { delegateNode = Node.EMPTY; } } return delegateNode; } @MultiViewElement.Registration( displayName = "#LBL_Detector_EDITOR", iconBase = "de/fub/maps/project/detector/filetype/detector.png", mimeType = "text/detector+xml", persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED, preferredID = "Detector", position = 3000) @Messages("LBL_Detector_EDITOR=Source") public static MultiViewEditorElement createEditor(Lookup lkp) { return new DetectorEditorElement(lkp); } public synchronized DetectorDescriptor getDetectorDescriptor() throws JAXBException, IOException { if (detectorDescriptor == null) { detectorDescriptor = DetectorUtils.getDetectorDescriptor(DetectorDataObject.this); } return detectorDescriptor; } public void save() { try { DetectorUtils.saveDetector(DetectorDataObject.this); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } public void modifySourceEditor() { FileUtil.runAtomicAction(new Runnable() { @Override public void run() { DataEditorSupport editorSupport = getLookup().lookup(DataEditorSupport.class); try { if (editorSupport.isDocumentLoaded()) { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(DetectorDescriptor.class); javax.xml.bind.Marshaller marshaller = jaxbCtx.createMarshaller(); marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8"); //NOI18N marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); StringWriter stringWriter = new StringWriter(); marshaller.marshal(detectorDescriptor, stringWriter); StyledDocument document = editorSupport.getDocument(); document.remove(0, document.getLength()); document.insertString(0, stringWriter.toString(), null); editorSupport.saveDocument(); setModified(false); } else { save(); } } catch (javax.xml.bind.JAXBException ex) { Exceptions.printStackTrace(ex); } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } }); } public void updateEditor() { DataEditorSupport editorSupport = getLookup().lookup(DataEditorSupport.class); try { if (editorSupport.isDocumentLoaded()) { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(DetectorDescriptor.class); javax.xml.bind.Marshaller marshaller = jaxbCtx.createMarshaller(); marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8"); //NOI18N marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); StringWriter stringWriter = new StringWriter(); marshaller.marshal(detectorDescriptor, stringWriter); StyledDocument document = editorSupport.getDocument(); document.remove(0, document.getLength()); document.insertString(0, stringWriter.toString(), null); } } catch (javax.xml.bind.JAXBException ex) { Exceptions.printStackTrace(ex); } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } } @Override protected FileObject handleRename(String name) throws IOException { try { getDetectorDescriptor().setName(name); save(); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } return super.handleRename(name); //To change body of generated methods, choose Tools | Templates. } public void addChangeListener(ChangeListener listener) { cs.addChangeListener(listener); } public void removeChangeListener(ChangeListener listener) { cs.removeChangeListener(listener); } private class FileChangeAdapterImpl extends FileChangeAdapter { public FileChangeAdapterImpl() { } @Override public void fileChanged(FileEvent fe) { detectorDescriptor = null; cs.fireChange(); } } private class SaveAsTamplateHandlerImpl implements SaveAsTemplateAction.SaveAsTemplateHandler { @Override public void createTemplate(String templateName, DataObject templateFromThisDataObject) throws IOException { if (templateFromThisDataObject instanceof DetectorDataObject) { try { DetectorDataObject detectorDataObject = (DetectorDataObject) templateFromThisDataObject; DetectorDescriptor detectorDescr = DetectorUtils.getDetectorDescriptor(detectorDataObject); detectorDescr.setName(templateName); DataSets datasets = detectorDescr.getDatasets(); datasets.getInferenceSet().getDatasetList().clear(); datasets.getTrainingSet().getTransportModeList().clear(); FileObject detectorTemplates = FileUtil.getConfigFile("Templates/Detectors"); if (detectorTemplates == null) { FileObject templateFolder = FileUtil.getConfigFile("Templates"); if (templateFolder != null) { detectorTemplates = templateFolder.createFolder("Detectors"); } else { throw new IOException("Couldn't Templates folder!"); } } templateName = templateName.endsWith(".dec") ? templateName : MessageFormat.format("{0}.dec", templateName); FileObject templateFile = detectorTemplates.createData(templateName); DataObject.find(templateFile).setTemplate(true); DetectorUtils.saveDetector(templateFile, detectorDescr); } catch (JAXBException ex) { throw new IOException(ex); } } } } private static class DetectorEditorElement extends MultiViewEditorElement { private static final long serialVersionUID = 1L; private Lookup lkp = null; public DetectorEditorElement(Lookup lookup) { super(lookup); } @Override public Lookup getLookup() { if (lkp == null) { JComponent visualRepresentation = getVisualRepresentation(); lkp = new ProxyLookup(Lookups.singleton(visualRepresentation), super.getLookup()); } return lkp; } } }