/* * Copyright 2013 Serdar. * * 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 de.fub.maps.project.aggregator.filetype; import de.fub.maps.project.aggregator.factories.nodes.AggregatorNode; import de.fub.maps.project.aggregator.xml.AggregatorDescriptor; import de.fub.maps.project.models.Aggregator; import de.fub.maps.project.utils.AggregatorUtils; import de.fub.utilsmodule.actions.SaveAsTemplateAction; import de.fub.utilsmodule.xml.jax.JAXBUtil; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.text.MessageFormat; import java.util.Collections; 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.AbstractLookup; import org.openide.util.lookup.InstanceContent; import org.openide.util.lookup.ProxyLookup; import org.openide.windows.TopComponent; import org.xml.sax.InputSource; @Messages({ "LBL_AggregationBuilder_LOADER=Files of AggregationBuilder" }) @MIMEResolver.ExtensionRegistration( displayName = "#LBL_AggregationBuilder_LOADER", mimeType = "text/aggregationbuilder+xml", extension = {"agg", "Agg", "AGG"}) @MIMEResolver.NamespaceRegistration( displayName = "#LBL_AggregationBuilder_LOADER", checkedExtension = {"agg", "Agg", "AGG"}, mimeType = "text/aggregationbuilder+xml", elementNS = {"http://inf.fu-berlin.de/mapsforge/aggregation/schema"}, elementName = "aggregator") @DataObject.Registration( mimeType = "text/aggregationbuilder+xml", iconBase = "de/fub/maps/project/aggregator/filetype/aggregationBuilderIcon.png", displayName = "#LBL_AggregationBuilder_LOADER", position = 300) @ActionReferences({ @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID(category = "System", id = "org.openide.actions.OpenAction"), position = 100, separatorAfter = 200), @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID(category = "Edit", id = "org.openide.actions.CutAction"), position = 300), @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"), position = 400, separatorAfter = 500), @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"), position = 600), // @ActionReference( // path = "Loaders/text/aggregationbuilder+xml/Actions", // id = // @ActionID(category = "System", id = "org.openide.actions.RenameAction"), // position = 700, // separatorAfter = 800), @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID( category = "System", id = "de.fub.utilsmodule.actions.SaveAsTemplateAction"), position = 900, separatorAfter = 1000), @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"), position = 1100, separatorAfter = 1200), // @ActionReference( // path = "Loaders/text/aggregationbuilder+xml/Actions", // id = // @ActionID(category = "System", id = "org.openide.actions.ToolsAction"), // position = 1300), @ActionReference( path = "Loaders/text/aggregationbuilder+xml/Actions", id = @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"), position = 1400) }) public class AggregatorDataObject extends MultiDataObject { private static final long serialVersionUID = 1L; private final InstanceContent ic = new InstanceContent(); private transient Lookup lookup; private transient final ChangeSupport cs = new ChangeSupport(this); private transient AggregatorNode delegateNode = null; private transient AggregatorDescriptor aggregator = null; private transient final FileChangeAdapter fileChangeListener = new FileChangeAdapterImpl(); public AggregatorDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { super(pf, loader); registerEditor("text/aggregationbuilder+xml", true); pf.addFileChangeListener(FileUtil.weakFileChangeListener(fileChangeListener, pf)); InputSource inputSource = DataObjectAdapters.inputSource(AggregatorDataObject.this); CheckXMLSupport checkXMLSupport = new CheckXMLSupport(inputSource); ValidateXMLSupport validateXMLSupport = new ValidateXMLSupport(inputSource); getCookieSet().add(checkXMLSupport); getCookieSet().add(validateXMLSupport); getCookieSet().add(new SaveAsTemplateHandlerImpl()); } @Override protected void handleDelete() throws IOException { try { String cacheFolderPath = getAggregatorDescriptor().getCacheFolderPath(); if (cacheFolderPath != null) { File file = new File(cacheFolderPath); if (file.exists()) { DataObject.find(FileUtil.toFileObject(file)).delete(); } } } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } super.handleDelete(); //To change body of generated methods, choose Tools | Templates. } @Override protected FileObject handleRename(String name) throws IOException { try { getAggregatorDescriptor().setName(name); } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } return super.handleRename(name); } @Override public Lookup getLookup() { if (lookup == null) { lookup = new ProxyLookup(new AbstractLookup(ic), super.getLookup()); } return lookup; } public synchronized AggregatorDescriptor getAggregatorDescriptor() throws IOException, JAXBException { if (aggregator == null) { InputStream inputStream = null; try { inputStream = getPrimaryFile().getInputStream(); javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(AggregatorDescriptor.class); javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller(); aggregator = (AggregatorDescriptor) unmarshaller.unmarshal(inputStream); aggregator.setDatasources(Collections.synchronizedList(aggregator.getDatasources())); } finally { if (inputStream != null) { inputStream.close(); } } } return aggregator; } @Override protected int associateLookup() { return 1; } public void save() { FileUtil.runAtomicAction(new Runnable() { @Override public void run() { try { File file = FileUtil.toFile(getPrimaryFile()); if (file != null) { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(AggregatorDescriptor.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); marshaller.marshal(aggregator, file); FileUtil.refreshFor(file); } } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } } }); } public void modifySourceEditor() { FileUtil.runAtomicAction(new Runnable() { @Override public void run() { try { DataEditorSupport editorSupport = getLookup().lookup(DataEditorSupport.class); if (editorSupport.isDocumentLoaded()) { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(AggregatorDescriptor.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(aggregator, stringWriter); StyledDocument document = editorSupport.getDocument(); if (document != null) { document.remove(0, document.getLength()); document.insertString(0, stringWriter.toString(), null); editorSupport.saveDocument(); setModified(false); } } else { File file = FileUtil.toFile(getPrimaryFile()); if (file != null) { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(AggregatorDescriptor.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); marshaller.marshal(aggregator, file); FileUtil.refreshFor(file); } } } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } }); } public void updateSourceEditor() { DataEditorSupport editorSupport = getLookup().lookup(DataEditorSupport.class); if (editorSupport.isDocumentLoaded()) { try { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(AggregatorDescriptor.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(aggregator, stringWriter); StyledDocument document = editorSupport.getDocument(); document.remove(0, document.getLength()); document.insertString(0, stringWriter.toString(), null); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } } } @MultiViewElement.Registration( displayName = "#LBL_AggregationBuilder_EDITOR", iconBase = "de/fub/maps/project/aggregator/filetype/aggregationBuilderIcon.png", mimeType = "text/aggregationbuilder+xml", persistenceType = TopComponent.PERSISTENCE_NEVER, preferredID = "AggregationBuilder", position = 3000) @Messages("LBL_AggregationBuilder_EDITOR=Source") public static MultiViewEditorElement createEditor(Lookup lkp) { return new MultiViewEditorElement(lkp); } @Override protected Node createNodeDelegate() { if (delegateNode == null) { delegateNode = new AggregatorNode(new Aggregator(AggregatorDataObject.this)); } return delegateNode; } 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) { try { aggregator = null; getAggregatorDescriptor(); cs.fireChange(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } } } private class SaveAsTemplateHandlerImpl implements SaveAsTemplateAction.SaveAsTemplateHandler { @Override public void createTemplate(String templateName, DataObject templateFromThisDataObject) throws IOException { if (templateFromThisDataObject instanceof AggregatorDataObject) { try { AggregatorDataObject dataObject = (AggregatorDataObject) templateFromThisDataObject; AggregatorDescriptor aggregatorDescriptor = AggregatorUtils.getAggregatorDescritpor(dataObject); aggregatorDescriptor.setName(templateName); if (aggregatorDescriptor.getDatasources() != null) { aggregatorDescriptor.getDatasources().clear(); } FileObject aggregatorTemplates = FileUtil.getConfigFile("Templates/Aggregators"); if (aggregatorTemplates == null) { FileObject templateFolder = FileUtil.getConfigFile("Tamplates"); if (templateFolder != null) { aggregatorTemplates = templateFolder.createFolder("Aggregators"); } else { throw new IOException("Couldn't find Template folder!"); } } templateName = templateName.endsWith(".agg") ? templateName : MessageFormat.format("{0}.agg", templateName); FileObject aggregatorTemplate = aggregatorTemplates.createData(templateName); DataObject.find(aggregatorTemplate).setTemplate(true); JAXBUtil.saveDetector(aggregatorTemplate, aggregatorDescriptor); } catch (JAXBException ex) { Exceptions.printStackTrace(ex); } } } } }