/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
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.
*/
/*
* XMLFileReader.java
*
* Created on 09. Mai 2003, 16:05
*/
package org.geogebra.desktop.io;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;
import org.geogebra.common.jre.gui.MyImageJre;
import org.geogebra.common.jre.io.MyXMLioJre;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.util.StringUtil;
import org.geogebra.common.util.debug.Log;
import org.geogebra.desktop.gui.MyImageD;
import org.geogebra.desktop.main.AppD;
import org.geogebra.desktop.util.UtilD;
/**
*
* @author Markus Hohenwarter
*/
public class MyXMLioD extends MyXMLioJre {
/**
*
* @param kernel
* Kernel
* @param cons
* Construction
*/
public MyXMLioD(Kernel kernel, Construction cons) {
super(kernel, cons);
}
@Override
protected final void readZip(ZipInputStream zip, boolean isGGTfile)
throws Exception {
// we have to read everything (i.e. all images)
// before we process the XML file, that's why we
// read the XML file into a buffer first
byte[] xmlFileBuffer = null;
byte[] macroXmlFileBuffer = null;
byte[] defaults2dXmlFileBuffer = null;
byte[] defaults3dXmlFileBuffer = null;
boolean xmlFound = false;
boolean macroXMLfound = false;
boolean javaScriptFound = false;
// get all entries from the zip archive
while (true) {
ZipEntry entry = null;
try {
entry = zip.getNextEntry();
} catch (Exception e) {
Log.error(e.getMessage());
}
if (entry == null) {
break;
}
String name = entry.getName();
if (name.equals(XML_FILE)) {
// load xml file into memory first
xmlFileBuffer = UtilD.loadIntoMemory(zip);
xmlFound = true;
handler = getGGBHandler();
} else if (name.equals(XML_FILE_DEFAULTS_2D)) {
// load defaults xml file into memory first
defaults2dXmlFileBuffer = UtilD.loadIntoMemory(zip);
handler = getGGBHandler();
} else if (app.is3D() && name.equals(XML_FILE_DEFAULTS_3D)) {
// load defaults xml file into memory first
defaults3dXmlFileBuffer = UtilD.loadIntoMemory(zip);
handler = getGGBHandler();
} else if (name.equals(XML_FILE_MACRO)) {
// load macro xml file into memory first
macroXmlFileBuffer = UtilD.loadIntoMemory(zip);
macroXMLfound = true;
handler = getGGBHandler();
} else if (name.equals(JAVASCRIPT_FILE)) {
// load JavaScript
kernel.setLibraryJavaScript(UtilD.loadIntoString(zip));
javaScriptFound = true;
} else if (StringUtil.toLowerCase(name).endsWith("svg")) {
String svg = UtilD.loadIntoString(zip);
MyImageD img = new MyImageD(svg, name);
((AppD) app).addExternalImage(name, img);
} else {
// try to load image
try {
BufferedImage img = ImageIO.read(zip);
if ("".equals(name)) {
Log.warn("image in zip file with empty name");
} else {
((AppD) app).addExternalImage(name, new MyImageD(img));
}
} catch (IOException e) {
Log.debug("readZipFromURL: image could not be loaded: "
+ name);
e.printStackTrace();
}
}
// get next entry
try {
zip.closeEntry();
} catch (Exception e) {
Log.error(e.getMessage());
}
}
zip.close();
if (!isGGTfile) {
// ggb file: remove all macros from kernel before processing
kernel.removeAllMacros();
}
// process macros
if (macroXmlFileBuffer != null) {
// don't clear kernel for macro files
kernel.getConstruction().setFileLoading(true);
processXMLBuffer(macroXmlFileBuffer, !isGGTfile, isGGTfile);
kernel.getConstruction().setFileLoading(false);
}
// process construction
if (!isGGTfile && xmlFileBuffer != null) {
kernel.getConstruction().setFileLoading(true);
app.getCompanion().resetEuclidianViewForPlaneIds();
processXMLBuffer(xmlFileBuffer, !macroXMLfound, isGGTfile);
kernel.getConstruction().setFileLoading(false);
}
// process defaults (after construction for labeling styles)
if (defaults2dXmlFileBuffer != null) {
kernel.getConstruction().setFileLoading(true);
processXMLBuffer(defaults2dXmlFileBuffer, false, true);
kernel.getConstruction().setFileLoading(false);
}
if (defaults3dXmlFileBuffer != null) {
kernel.getConstruction().setFileLoading(true);
processXMLBuffer(defaults3dXmlFileBuffer, false, true);
kernel.getConstruction().setFileLoading(false);
}
if (!javaScriptFound && !isGGTfile) {
kernel.resetLibraryJavaScript();
}
if (!(macroXMLfound || xmlFound)) {
throw new Exception("No XML data found in file.");
}
}
@Override
final protected MyImageJre getExportImage(double width, double height) {
return new MyImageD(((AppD) app).getExportImage(THUMBNAIL_PIXELS_X,
THUMBNAIL_PIXELS_Y));
}
@Override
final protected MyImageJre getExternalImage(String fileName) {
return ((AppD) app).getExternalImage(fileName);
}
@Override
final protected void writeImage(MyImageJre img, String ext, OutputStream os)
throws IOException {
ImageIO.write((BufferedImage) ((MyImageD) img).getImage(), ext, os);
}
/**
* Get the preview image of a ggb file.
*
* @param file
* file
* @throws IOException
* when file is not valid ggb
* @return preview image
*/
public final static BufferedImage getPreviewImage(File file)
throws IOException {
// just allow preview images for ggb files
if (!file.getName().endsWith(".ggb")) {
throw new IllegalArgumentException(
"Preview image source file has to be of the type .ggb");
}
FileInputStream fis = new FileInputStream(file);
ZipInputStream zip = new ZipInputStream(fis);
BufferedImage result = null;
// get all entries from the zip archive
while (true) {
ZipEntry entry = zip.getNextEntry();
if (entry == null) {
break;
}
if (entry.getName().equals(XML_FILE_THUMBNAIL)) {
result = ImageIO.read(zip);
break;
}
// get next entry
zip.closeEntry();
}
zip.close();
fis.close();
return result;
}
}