/*
* 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.datasource.spi.actions;
import de.fub.gpxmodule.xml.Gpx;
import de.fub.gpxmodule.xml.ObjectFactory;
import de.fub.gpxmodule.xml.Trk;
import de.fub.maps.project.datasource.GPXDatasourceNode;
import de.fub.maps.project.datasource.MapsDatasourceNodeFactory;
import de.fub.maps.project.datasource.spi.TrackSegmentBehaviour;
import de.fub.maps.project.datasource.spi.TrksegWrapper;
import de.fub.utilsmodule.icons.IconRegister;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;
import java.text.MessageFormat;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.cookies.OpenCookie;
import org.openide.explorer.ExplorerManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx;
/**
*
* @author Serdar
*/
public class TrackSemgentExportAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private ExplorerManager explorerManger;
private ExportDialog exportDialog;
public TrackSemgentExportAction() {
super();
Image image = IconRegister.findRegisteredIcon("exportIcon.png");
if (image != null) {
putValue(Action.SMALL_ICON, new ImageIcon(image));
}
}
public TrackSemgentExportAction(ExplorerManager explorerManager) {
this();
this.explorerManger = explorerManager;
}
@Override
public void actionPerformed(ActionEvent e) {
exportDialog = new ExportDialog();
Object[] options = exportDialog.getOptions();
DialogDescriptor dd = new DialogDescriptor(
exportDialog,
"Save Dialog",
true,
options,
exportDialog.getSaveButton(),
DialogDescriptor.BOTTOM_ALIGN,
HelpCtx.DEFAULT_HELP,
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
handler(e);
}
});
dd.setClosingOptions(options);
DialogDisplayer.getDefault().createDialog(dd).setVisible(true);
}
/**
* this method check whether the gpx extension if present and if not it
* appends the extension.
*
* @param fileName
* @return a String with '.gpx' extension
*/
private String preprocessFileName(String fileName) {
if (!fileName.endsWith(".gpx")) {
fileName = MessageFormat.format("{0}.gpx", fileName);
}
return fileName;
}
private Gpx getExportGpx() {
Children children = explorerManger.getRootContext().getChildren();
final Gpx gpx = new Gpx();
for (Node node : children.getNodes()) {
if (node instanceof TrackSegmentBehaviour) {
TrksegWrapper trkseg = node.getLookup().lookup(TrksegWrapper.class);
TrackSegmentBehaviour trackNode = (TrackSegmentBehaviour) node;
if (trackNode.isVisible() && trkseg != null) {
Trk trk = new Trk();
trk.setName(trkseg.getTrackName());
trk.setDesc(trkseg.getTrackDescription());
trk.getTrkseg().add(trkseg.getTrkseg());
gpx.getTrk().add(trk);
}
}
}
return gpx;
}
private void handler(ActionEvent event) {
if (exportDialog != null && explorerManger != null) {
if (event.getSource() == exportDialog.getOptions()[0]) {
final boolean openAfterSave = exportDialog.getOpenAfterSave().isSelected();
final Object selectedItem = exportDialog.getFolderName().getSelectedItem();
String fileName = exportDialog.getFileName().getText();
if (selectedItem instanceof String && fileName != null) {
final String folderName = (String) selectedItem;
fileName = preprocessFileName(fileName);
final Gpx gpx = getExportGpx();
GPXDatasourceNode datasourceNode = MapsDatasourceNodeFactory.gpxDatasourceNode;
if (datasourceNode != null) {
final DataObject dataObject = datasourceNode.getLookup().lookup(DataObject.class);
if (dataObject != null) {
final String fileN = fileName;
FileUtil.runAtomicAction(new SaveImplemention(dataObject, folderName, fileN, gpx, openAfterSave));
}
}
}
}
}
}
private static class SaveImplemention implements Runnable {
private final DataObject dataObject;
private final String folderName;
private final String fileName;
private final Gpx gpx;
private final boolean openAfterSave;
public SaveImplemention(DataObject dataObject, String folderName, String fileName, Gpx gpx, boolean openAfterSave) {
this.dataObject = dataObject;
this.folderName = folderName;
this.fileName = fileName;
this.gpx = gpx;
this.openAfterSave = openAfterSave;
}
@Override
public void run() {
OutputStream outputStream = null;
FileObject storedFileObject = null;
try {
storedFileObject = getOrCreateFileObject();
outputStream = storedFileObject.getOutputStream();
// write into the outputstream the gpx data
Marshaller marshaller = createMarshaller();
marshaller.marshal(new ObjectFactory().createGpx(gpx), outputStream);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} catch (JAXBException ex) {
Exceptions.printStackTrace(ex);
} finally {
// close stream
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
checkAndOpen(storedFileObject);
}
}
private FileObject getOrCreateFileObject() throws IOException {
FileObject storedFileObject = null;
// get parent folder
FileObject datasourceFileObject = dataObject.getPrimaryFile();
// get sub folder in which the gpx data will be stored
FileObject folderObject = datasourceFileObject.getFileObject(folderName);
// if the folder does not exist create the folder
if (folderObject == null) {
folderObject = datasourceFileObject.createFolder(folderName);
}
FileObject fileObject = folderObject.getFileObject(fileName);
String alternativeFileName = fileName;
// in case the previouse file name check-methods failed
// we create a free file name if the given fileName already
// exists in the current subfolder
if (fileObject != null) {
alternativeFileName = FileUtil.findFreeFileName(folderObject, fileName, "gpx");
}
storedFileObject = folderObject.createData(alternativeFileName);
return storedFileObject;
}
private Marshaller createMarshaller() throws JAXBException {
javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(Gpx.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);
return marshaller;
}
private void checkAndOpen(FileObject fileObject) {
// if the user selected to open the previously saved file
// the respective editor will be opened.
if (openAfterSave && fileObject != null) {
try {
DataObject storedDataObject = DataObject.find(fileObject);
OpenCookie openCookie = storedDataObject.getLookup().lookup(OpenCookie.class);
if (openCookie != null) {
openCookie.open();
}
} catch (DataObjectNotFoundException ex) {
Exceptions.printStackTrace(ex);
}
}
}
}
}