提交 5b001867 编写于 作者: M Mathieu Bastian

Separate project zip file into multiple entries, one for the project and one...

Separate project zip file into multiple entries, one for the project and one for each workspace. Improve error handling.
上级 0ad61139
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.desktop.project;
......@@ -53,7 +53,6 @@ import org.gephi.desktop.importer.api.ImportControllerUI;
import org.gephi.desktop.mrufiles.api.MostRecentFiles;
import org.gephi.desktop.project.api.ProjectControllerUI;
import org.gephi.io.importer.api.FileType;
import org.gephi.io.importer.api.ImportController;
import org.gephi.project.api.Project;
import org.gephi.project.api.ProjectController;
import org.gephi.project.api.ProjectInformation;
......@@ -108,20 +107,20 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
//Project IO executor
longTaskExecutor = new LongTaskExecutor(true, "Project IO");
longTaskExecutor.setDefaultErrorHandler(new LongTaskErrorHandler() {
public void fatalError(Throwable t) {
unlockProjectActions();
String txt = NbBundle.getMessage(ProjectControllerUIImpl.class, "ProjectControllerUI.error.open");
String message = txt + "\n\n" + t.getMessage();
if (t.getCause() != null) {
message = txt + "\n\n" + t.getCause().getClass().getSimpleName() + " - " + t.getCause().getMessage();
}
NotifyDescriptor.Message msg = new NotifyDescriptor.Message(message, NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(msg);
// String txt = NbBundle.getMessage(ProjectControllerUIImpl.class, "ProjectControllerUI.error.open");
// String message = txt + "\n\n" + t.getMessage();
// if (t.getCause() != null) {
// message = txt + "\n\n" + t.getCause().getClass().getSimpleName() + " - " + t.getCause().getMessage();
// }
// NotifyDescriptor.Message msg = new NotifyDescriptor.Message(message, NotifyDescriptor.WARNING_MESSAGE);
// DialogDisplayer.getDefault().notify(msg);
Logger.getLogger("").log(Level.SEVERE, "", t.getCause());
}
});
longTaskExecutor.setLongTaskListener(new LongTaskListener() {
public void taskFinished(LongTask task) {
unlockProjectActions();
}
......@@ -134,7 +133,6 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
final Runnable saveTask = controller.saveProject(project, file);
final String fileName = file.getName();
Runnable saveRunnable = new Runnable() {
public void run() {
saveTask.run();
//Status line
......@@ -212,7 +210,6 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
//Modifying Title bar
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
String title = frame.getTitle();
......@@ -261,7 +258,6 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
//Title bar
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
String title = frame.getTitle();
......@@ -288,11 +284,9 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
final Runnable loadTask = controller.openProject(file);
final String fileName = file.getName();
Runnable loadRunnable = new Runnable() {
public void run() {
loadTask.run();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
String title = frame.getTitle() + " - " + fileName;
......@@ -319,7 +313,6 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
//Title bar
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
String title = frame.getTitle();
......@@ -484,7 +477,6 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
final Project project = controller.getCurrentProject();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
String title = frame.getTitle() + " - " + project.getLookup().lookup(ProjectInformation.class).getName();
......@@ -527,7 +519,6 @@ public class ProjectControllerUIImpl implements ProjectControllerUI {
//Title bar
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
String title = frame.getTitle();
......
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.project.api;
/**
......@@ -54,4 +54,6 @@ public interface WorkspaceProvider {
public boolean hasCurrentWorkspace();
public Workspace[] getWorkspaces();
public Workspace getWorkspace(int id);
}
......@@ -101,4 +101,8 @@ public class ProjectImpl implements Project, Lookup.Provider, Serializable {
public void setWorkspaceIds(int ids) {
workspaceIds.set(ids);
}
public int getWorkspaceIds() {
return workspaceIds.get();
}
}
......@@ -105,4 +105,8 @@ public class ProjectsImpl implements Projects, Serializable {
public void setProjectIds(int id) {
projectIds.set(id);
}
public int getProjectIds() {
return projectIds.get();
}
}
......@@ -110,6 +110,16 @@ public class WorkspaceProviderImpl implements WorkspaceProvider {
return workspaces.toArray(new Workspace[0]);
}
@Override
public synchronized Workspace getWorkspace(int id) {
for (Workspace w : workspaces) {
if (w.getId() == id) {
return w;
}
}
return null;
}
public synchronized void setCurrentWorkspace(Workspace currentWorkspace) {
this.currentWorkspace = (WorkspaceImpl) currentWorkspace;
}
......
......@@ -65,43 +65,26 @@ public class GephiReader implements Cancellable {
private ProjectImpl project;
private boolean cancel = false;
private final Map<String, WorkspacePersistenceProvider> providers;
private WorkspacePersistenceProvider currentProvider;
public GephiReader() {
providers = new LinkedHashMap<String, WorkspacePersistenceProvider>();
for (WorkspacePersistenceProvider w : Lookup.getDefault().lookupAll(WorkspacePersistenceProvider.class)) {
try {
String id = w.getIdentifier();
if (id != null && !id.isEmpty()) {
providers.put(w.getIdentifier(), w);
}
} catch (Exception e) {
}
}
}
@Override
public boolean cancel() {
cancel = true;
return true;
}
public Project readAll(XMLStreamReader reader, ProjectsImpl projects) throws Exception {
public Project readProject(XMLStreamReader reader, ProjectsImpl projects) throws Exception {
boolean end = false;
while (reader.hasNext() && !end) {
Integer eventType = reader.next();
if (eventType.equals(XMLEvent.START_ELEMENT)) {
String name = reader.getLocalName();
if ("gephiFile".equalsIgnoreCase(name)) {
if ("projectFile".equalsIgnoreCase(name)) {
//Version
String version = reader.getAttributeValue(null, "version");
if (version == null || version.isEmpty() || Double.parseDouble(version) < 0.7) {
throw new GephiFormatException("Gephi project file version must be at least 0.7");
}
} else if ("projects".equalsIgnoreCase(name)) {
Integer ids = Integer.parseInt(reader.getAttributeValue(null, "ids"));
projects.setProjectIds(ids);
} else if ("project".equalsIgnoreCase(name)) {
String projectName = reader.getAttributeValue(null, "name");
this.project = new ProjectImpl(projectName);
......@@ -111,14 +94,6 @@ public class GephiReader implements Cancellable {
Integer workspaceIds = Integer.parseInt(reader.getAttributeValue(null, "ids"));
project.setWorkspaceIds(workspaceIds);
}
} else if ("workspace".equalsIgnoreCase(name)) {
Workspace workspace = readWorkspace(reader);
//Current workspace
if (workspace.getLookup().lookup(WorkspaceInformationImpl.class).isOpen()) {
WorkspaceProviderImpl workspaces = project.getLookup().lookup(WorkspaceProviderImpl.class);
workspaces.setCurrentWorkspace(workspace);
}
}
} else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
if ("project".equalsIgnoreCase(reader.getLocalName())) {
......@@ -131,40 +106,67 @@ public class GephiReader implements Cancellable {
}
public Workspace readWorkspace(XMLStreamReader reader) throws Exception {
Integer workspaceId;
if (reader.getAttributeValue(null, "id") == null) {
workspaceId = project.nextWorkspaceId();
} else {
workspaceId = Integer.parseInt(reader.getAttributeValue(null, "id"));
}
WorkspaceImpl workspace = null;
boolean end = false;
while (reader.hasNext() && !end) {
Integer eventType = reader.next();
if (eventType.equals(XMLEvent.START_ELEMENT)) {
String name = reader.getLocalName();
if ("workspaceFile".equalsIgnoreCase(name)) {
//Version
String version = reader.getAttributeValue(null, "version");
if (version == null || version.isEmpty() || Double.parseDouble(version) < 0.7) {
throw new GephiFormatException("Gephi project file version must be at least 0.7");
}
} else if ("workspace".equalsIgnoreCase(name)) {
//Id
Integer workspaceId;
if (reader.getAttributeValue(null, "id") == null) {
workspaceId = project.nextWorkspaceId();
} else {
workspaceId = Integer.parseInt(reader.getAttributeValue(null, "id"));
}
WorkspaceImpl workspace = project.getLookup().lookup(WorkspaceProviderImpl.class).newWorkspace(workspaceId);
WorkspaceInformationImpl info = workspace.getLookup().lookup(WorkspaceInformationImpl.class);
workspace = project.getLookup().lookup(WorkspaceProviderImpl.class).newWorkspace(workspaceId);
WorkspaceInformationImpl info = workspace.getLookup().lookup(WorkspaceInformationImpl.class);
//Name
info.setName(reader.getAttributeValue(null, "name"));
//Name
info.setName(reader.getAttributeValue(null, "name"));
//Status
String workspaceStatus = reader.getAttributeValue(null, "status");
if (workspaceStatus.equals("open")) {
info.open();
} else if (workspaceStatus.equals("closed")) {
info.close();
} else {
info.invalid();
}
//Status
String workspaceStatus = reader.getAttributeValue(null, "status");
if (workspaceStatus.equals("open")) {
info.open();
} else if (workspaceStatus.equals("closed")) {
info.close();
} else {
info.invalid();
}
//Hack to set this workspace active, when readers need to use attributes for instance
ProjectControllerImpl pc = Lookup.getDefault().lookup(ProjectControllerImpl.class);
pc.setTemporaryOpeningWorkspace(workspace);
//Hack to set this workspace active, when readers need to use attributes for instance
ProjectControllerImpl pc = Lookup.getDefault().lookup(ProjectControllerImpl.class);
pc.setTemporaryOpeningWorkspace(workspace);
//WorkspacePersistent
readWorkspaceChildren(workspace, reader);
if (currentProvider != null) {
//One provider not correctly closed
throw new GephiFormatException("The '" + currentProvider.getIdentifier() + "' persistence provider is not ending read.");
//WorkspacePersistent
readWorkspaceChildren(workspace, reader);
if (currentProvider != null) {
//One provider not correctly closed
throw new GephiFormatException("The '" + currentProvider.getIdentifier() + "' persistence provider is not ending read.");
}
pc.setTemporaryOpeningWorkspace(null);
//Current workspace
if (info.isOpen()) {
WorkspaceProviderImpl workspaces = project.getLookup().lookup(WorkspaceProviderImpl.class);
workspaces.setCurrentWorkspace(workspace);
}
}
} else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
if ("workspace".equalsIgnoreCase(reader.getLocalName())) {
end = true;
}
}
}
pc.setTemporaryOpeningWorkspace(null);
return workspace;
}
......@@ -175,7 +177,7 @@ public class GephiReader implements Cancellable {
Integer eventType = reader.next();
if (eventType.equals(XMLEvent.START_ELEMENT)) {
String name = reader.getLocalName();
WorkspacePersistenceProvider pp = providers.get(name);
WorkspacePersistenceProvider pp = getPersistenceProviders().get(name);
if (pp != null) {
currentProvider = pp;
try {
......@@ -191,4 +193,18 @@ public class GephiReader implements Cancellable {
}
}
}
private Map<String, WorkspacePersistenceProvider> getPersistenceProviders() {
Map<String, WorkspacePersistenceProvider> providers = new LinkedHashMap<String, WorkspacePersistenceProvider>();
for (WorkspacePersistenceProvider w : Lookup.getDefault().lookupAll(WorkspacePersistenceProvider.class)) {
try {
String id = w.getIdentifier();
if (id != null && !id.isEmpty()) {
providers.put(w.getIdentifier(), w);
}
} catch (Exception e) {
}
}
return providers;
}
}
......@@ -41,20 +41,23 @@
*/
package org.gephi.project.io;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;
import javax.xml.stream.XMLStreamWriter;
import org.gephi.project.api.Project;
import org.gephi.project.api.ProjectInformation;
import org.gephi.project.api.ProjectMetaData;
import org.gephi.project.api.Workspace;
import org.gephi.project.api.WorkspaceInformation;
import org.gephi.project.impl.WorkspaceProviderImpl;
import org.gephi.project.impl.ProjectImpl;
import org.gephi.project.spi.WorkspacePersistenceProvider;
import org.openide.util.Cancellable;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
/**
*
......@@ -62,57 +65,21 @@ import org.openide.util.Lookup;
*/
public class GephiWriter implements Cancellable {
private final Map<String, WorkspacePersistenceProvider> providers;
private static final String VERSION = "0.9";
public GephiWriter() {
providers = new LinkedHashMap<String, WorkspacePersistenceProvider>();
for (WorkspacePersistenceProvider w : Lookup.getDefault().lookupAll(WorkspacePersistenceProvider.class)) {
try {
String id = w.getIdentifier();
if (id != null && !id.isEmpty()) {
providers.put(w.getIdentifier(), w);
}
} catch (Exception e) {
}
}
}
public void writeAll(Project project, XMLStreamWriter writer) throws Exception {
public void writeProject(XMLStreamWriter writer, Project project) throws Exception {
writer.writeStartDocument("UTF-8", "1.0");
writer.writeStartElement("gephiFile");
writer.writeAttribute("version", "0.9");
writer.writeComment("File saved from Gephi 0.9.0");
writeCore(writer);
writeProject(writer, project);
writer.writeEndElement();
writer.writeEndDocument();
}
public void writeCore(XMLStreamWriter writer) throws Exception {
//Core
writer.writeStartElement("core");
writer.writeStartElement("lastModifiedDate");
//LastModifiedDate
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
writer.writeCharacters(sdf.format(cal.getTime()));
writer.writeComment("yyyy-MM-dd HH:mm:ss");
writer.writeStartElement("projectFile");
//Append
writer.writeEndElement();
writer.writeEndElement();
}
writeHeader(writer);
public void writeProject(XMLStreamWriter writer, Project project) throws Exception {
ProjectInformation info = project.getLookup().lookup(ProjectInformation.class);
ProjectMetaData metaData = project.getLookup().lookup(ProjectMetaData.class);
WorkspaceProviderImpl workspaces = project.getLookup().lookup(WorkspaceProviderImpl.class);
//Start Project
writer.writeStartElement("project");
writer.writeAttribute("name", info.getName());
writer.writeAttribute("ids", String.valueOf(((ProjectImpl) project).getWorkspaceIds()));
//MetaData
writer.writeStartElement("metadata");
......@@ -134,17 +101,21 @@ public class GephiWriter implements Cancellable {
writer.writeEndElement();
writer.writeEndElement();
//End Metadata
//Workspaces
writer.writeStartElement("workspaces");
for (Workspace ws : workspaces.getWorkspaces()) {
writeWorkspace(writer, ws);
}
writer.writeEndElement();
//End Project
writer.writeEndElement();
writer.writeEndDocument();
}
public void writeWorkspace(XMLStreamWriter writer, Workspace workspace) throws Exception {
writer.writeStartDocument("UTF-8", "1.0");
writer.writeStartElement("workspaceFile");
writeHeader(writer);
WorkspaceInformation info = workspace.getLookup().lookup(WorkspaceInformation.class);
writer.writeStartElement("workspace");
......@@ -160,18 +131,63 @@ public class GephiWriter implements Cancellable {
writeWorkspaceChildren(writer, workspace);
writer.writeEndElement();
writer.writeEndElement();
writer.writeEndDocument();
}
public void writeWorkspaceChildren(XMLStreamWriter writer, Workspace workspace) throws Exception {
for (WorkspacePersistenceProvider pp : providers.values()) {
for (Map.Entry<String, WorkspacePersistenceProvider> entry : getPersistenceProviders().entrySet()) {
try {
writer.writeComment("Persistence from " + pp.getClass().getName());
String identifier = entry.getKey();
WorkspacePersistenceProvider pp = entry.getValue();
writer.writeComment("Persistence from '" + identifier + "' (" + pp.getClass().getName() + ")");
pp.writeXML(writer, workspace);
} catch (UnsupportedOperationException e) {
}
}
}
private void writeHeader(XMLStreamWriter writer) throws Exception {
writer.writeAttribute("version", VERSION);
//LastModifiedDate
writer.writeStartElement("lastModifiedDate");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
writer.writeCharacters(sdf.format(cal.getTime()));
writer.writeComment("yyyy-MM-dd HH:mm:ss");
writer.writeEndElement();
writer.writeComment("File saved with " + getVersion());
}
private Map<String, WorkspacePersistenceProvider> getPersistenceProviders() {
Map<String, WorkspacePersistenceProvider> providers = new LinkedHashMap<String, WorkspacePersistenceProvider>();
for (WorkspacePersistenceProvider w : Lookup.getDefault().lookupAll(WorkspacePersistenceProvider.class)) {
try {
String id = w.getIdentifier();
if (id != null && !id.isEmpty()) {
providers.put(w.getIdentifier(), w);
}
} catch (Exception e) {
}
}
return providers;
}
private String getVersion() {
try {
return MessageFormat.format(
NbBundle.getBundle("org.netbeans.core.startup.Bundle").getString("currentVersion"), // NOI18N
new Object[]{System.getProperty("netbeans.buildnumber")} // NOI18N
);
} catch (Exception e) {
return "?";
}
}
@Override
public boolean cancel() {
return true;
......
......@@ -42,10 +42,12 @@
package org.gephi.project.io;
import java.io.File;
import java.io.FilterReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLReporter;
......@@ -58,8 +60,6 @@ import org.gephi.project.impl.ProjectsImpl;
import org.gephi.utils.longtask.spi.LongTask;
import org.gephi.utils.progress.Progress;
import org.gephi.utils.progress.ProgressTicket;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
......@@ -80,15 +80,67 @@ public class LoadTask implements LongTask, Runnable {
@Override
public void run() {
Progress.start(progressTicket);
Progress.setDisplayName(progressTicket, NbBundle.getMessage(LoadTask.class, "LoadTask.name"));
try {
Progress.start(progressTicket);
Progress.setDisplayName(progressTicket, NbBundle.getMessage(LoadTask.class, "LoadTask.name"));
FileObject fileObject = FileUtil.toFileObject(file);
if (FileUtil.isArchiveFile(fileObject)) {
//Unzip
fileObject = FileUtil.getArchiveRoot(fileObject).getChildren()[0];
Project project = null;
ZipFile zip = null;
try {
zip = new ZipFile(file, Charset.forName("UTF-8"));
//Reader
gephiReader = new GephiReader();
for (Enumeration<? extends ZipEntry> e = zip.entries(); e.hasMoreElements();) {
ZipEntry entry = e.nextElement();
InputStream is = null;
try {
is = zip.getInputStream(entry);
String name = entry.getName();
if (name.equals("Project_xml")) {
project = readProject(is);
} else if (name.contains("Workspace") && name.contains("xml")) {
readWorkspace(is);
}
} finally {
if (is != null) {
is.close();
}
}
if (cancel) {
break;
}
}
//Add project
ProjectControllerImpl projectController = Lookup.getDefault().lookup(ProjectControllerImpl.class);
if (project != null) {
if (!cancel) {
projectController.openProject(project);
}
}
} finally {
if (zip != null) {
zip.close();
}
}
} catch (Exception ex) {
if (ex instanceof GephiFormatException) {
throw (GephiFormatException) ex;
}
throw new GephiFormatException(GephiReader.class, ex);
}
Progress.finish(progressTicket);
}
private Project readProject(InputStream inputStream) throws Exception {
InputStreamReader isReader = null;
Xml10FilterReader filterReader = null;
XMLStreamReader reader = null;
try {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
if (inputFactory.isPropertySupported("javax.xml.stream.isValidating")) {
inputFactory.setProperty("javax.xml.stream.isValidating", Boolean.FALSE);
......@@ -99,30 +151,55 @@ public class LoadTask implements LongTask, Runnable {
System.out.println("Error:" + errorType + ", message : " + message);
}
});
InputStreamReader isReader = new InputStreamReader(fileObject.getInputStream(), "UTF-8");
Xml10FilterReader filterReader = new Xml10FilterReader(isReader);
XMLStreamReader reader = inputFactory.createXMLStreamReader(filterReader);
if (!cancel) {
ProjectControllerImpl projectController = Lookup.getDefault().lookup(ProjectControllerImpl.class);
ProjectsImpl projects = projectController.getProjects();
//GephiReader
gephiReader = new GephiReader();
Project project = gephiReader.readAll(reader, projects);
project.getLookup().lookup(ProjectInformationImpl.class).setFile(file);
isReader = new InputStreamReader(inputStream, "UTF-8");
filterReader = new Xml10FilterReader(isReader);
reader = inputFactory.createXMLStreamReader(filterReader);
ProjectControllerImpl projectController = Lookup.getDefault().lookup(ProjectControllerImpl.class);
ProjectsImpl projects = projectController.getProjects();
Project project = gephiReader.readProject(reader, projects);
project.getLookup().lookup(ProjectInformationImpl.class).setFile(file);
return project;
} finally {
if (reader != null) {
reader.close();
}
if (filterReader != null) {
filterReader.close();
}
}
}
//Add project
if (!cancel) {
projectController.openProject(project);
private void readWorkspace(InputStream inputStream) throws Exception {
InputStreamReader isReader = null;
Xml10FilterReader filterReader = null;
XMLStreamReader reader = null;
try {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
if (inputFactory.isPropertySupported("javax.xml.stream.isValidating")) {
inputFactory.setProperty("javax.xml.stream.isValidating", Boolean.FALSE);
}
inputFactory.setXMLReporter(new XMLReporter() {
@Override
public void report(String message, String errorType, Object relatedInformation, Location location) throws XMLStreamException {
System.out.println("Error:" + errorType + ", message : " + message);
}
});
isReader = new InputStreamReader(inputStream, "UTF-8");
filterReader = new Xml10FilterReader(isReader);
reader = inputFactory.createXMLStreamReader(filterReader);
gephiReader.readWorkspace(reader);
} finally {
if (reader != null) {
reader.close();
}
Progress.finish(progressTicket);
} catch (Exception ex) {
if (ex instanceof GephiFormatException) {
throw (GephiFormatException) ex;
if (filterReader != null) {
filterReader.close();
}
if (isReader != null) {
isReader.close();
}
throw new GephiFormatException(GephiReader.class, ex);
}
}
......@@ -139,71 +216,4 @@ public class LoadTask implements LongTask, Runnable {
public void setProgressTicket(ProgressTicket progressTicket) {
this.progressTicket = progressTicket;
}
/**
* {@link FilterReader} to skip invalid xml version 1.0 characters. Valid
* Unicode chars for xml version 1.0 according to http://www.w3.org/TR/xml
* are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD], [#x10000-#x10FFFF]
* . In other words - any Unicode character, excluding the surrogate blocks,
* FFFE, and FFFF.
* <p>
* More details on the <a
* href="http://info.tsachev.org/2009/05/skipping-invalid-xml-character-with.html">blog</a>
*/
public class Xml10FilterReader extends FilterReader {
/**
* Creates filter reader which skips invalid xml characters.
*
* @param in original reader
*/
public Xml10FilterReader(Reader in) {
super(in);
}
/**
* Every overload of {@link Reader#read()} method delegates to this one
* so it is enough to override only this one. <br />
* To skip invalid characters this method shifts only valid chars to
* left and returns decreased value of the original read method. So
* after last valid character there will be some unused chars in the
* buffer.
*
* @return Number of read valid characters or <code>-1</code> if end of
* the underling reader was reached.
*/
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int read = super.read(cbuf, off, len);
/*
* If read chars are -1 then we have reach the end of the reader.
*/
if (read == -1) {
return -1;
}
/*
* pos will show the index where chars should be moved if there are gaps
* from invalid characters.
*/
int pos = off - 1;
for (int readPos = off; readPos < off + read; readPos++) {
if (XMLChar.isValid(cbuf[readPos])) {
pos++;
} else {
continue;
}
/*
* If there is gap(s) move current char to its position.
*/
if (pos < readPos) {
cbuf[pos] = cbuf[readPos];
}
}
/*
* Number of read valid characters.
*/
return pos - off + 1;
}
}
}
......@@ -45,11 +45,14 @@ import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import org.gephi.project.api.Project;
import org.gephi.project.api.Workspace;
import org.gephi.project.impl.WorkspaceProviderImpl;
import org.gephi.utils.longtask.spi.LongTask;
import org.gephi.utils.progress.Progress;
import org.gephi.utils.progress.ProgressTicket;
......@@ -79,81 +82,135 @@ public class SaveTask implements LongTask, Runnable {
@Override
public void run() {
//System.out.println("Save " + dataObject.getName());
ZipOutputStream zipOut = null;
BufferedOutputStream bufferedOutputStream = null;
boolean useTempFile = false;
Progress.start(progressTicket);
Progress.setDisplayName(progressTicket, NbBundle.getMessage(SaveTask.class, "SaveTask.name"));
File writeFile = null;
try {
Progress.start(progressTicket);
Progress.setDisplayName(progressTicket, NbBundle.getMessage(SaveTask.class, "SaveTask.name"));
FileObject fileObject = FileUtil.toFileObject(file);
writeFile = file;
if (writeFile.exists()) {
useTempFile = true;
String tempFileName = writeFile.getName() + "_temp";
writeFile = new File(writeFile.getParent(), tempFileName);
}
//Stream
int zipLevel = NbPreferences.forModule(SaveTask.class).getInt(ZIP_LEVEL_PREFERENCE, 9);
FileOutputStream outputStream = new FileOutputStream(writeFile);
zipOut = new ZipOutputStream(outputStream);
zipOut.setLevel(zipLevel);
String tempFileName = file.getName() + "_temp" + System.currentTimeMillis();
writeFile = new File(file.getParent(), tempFileName);
FileOutputStream outputStream = null;
ZipOutputStream zipOut = null;
BufferedOutputStream bos = null;
try {
//Stream
int zipLevel = NbPreferences.forModule(SaveTask.class).getInt(ZIP_LEVEL_PREFERENCE, 9);
outputStream = new FileOutputStream(writeFile);
zipOut = new ZipOutputStream(outputStream, Charset.forName("UTF-8"));
zipOut.setLevel(zipLevel);
bos = new BufferedOutputStream(zipOut);
//Writer
gephiWriter = new GephiWriter();
//Write Project
writeProject(gephiWriter, bos, zipOut);
//Write Workspace files
for (Workspace ws : project.getLookup().lookup(WorkspaceProviderImpl.class).getWorkspaces()) {
writeWorkspace(ws, gephiWriter, bos, zipOut);
if (cancel) {
break;
}
}
zipOut.putNextEntry(new ZipEntry("Project"));
gephiWriter = new GephiWriter();
zipOut.finish();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException ex1) {
}
}
if (zipOut != null) {
try {
zipOut.close();
} catch (IOException ex1) {
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ex1) {
}
}
}
//Create Writer and write project
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.FALSE);
bufferedOutputStream = new BufferedOutputStream(zipOut);
XMLStreamWriter writer = outputFactory.createXMLStreamWriter(bufferedOutputStream, "UTF-8");
gephiWriter.writeAll(project, writer);
writer.close();
//Close
zipOut.closeEntry();
zipOut.finish();
bufferedOutputStream.close();
//Clean and copy
if (useTempFile && !cancel) {
//Rename file
if (!cancel && writeFile.exists()) {
FileObject fileObject = FileUtil.toFileObject(file);
String name = fileObject.getName();
String ext = fileObject.getExt();
//Delete original file
fileObject.delete();
//Rename temp file
//Rename
FileObject tempFileObject = FileUtil.toFileObject(writeFile);
FileLock lock = tempFileObject.lock();
tempFileObject.rename(lock, name, ext);
lock.releaseLock();
} else if (cancel) {
//Delete temp file
FileObject tempFileObject = FileUtil.toFileObject(writeFile);
tempFileObject.delete();
}
Progress.finish(progressTicket);
} catch (Exception ex) {
if (zipOut != null) {
try {
zipOut.close();
} catch (IOException ex1) {
}
if (ex instanceof GephiFormatException) {
throw (GephiFormatException) ex;
}
if (bufferedOutputStream != null) {
throw new GephiFormatException(SaveTask.class, ex);
} finally {
if (writeFile != null && writeFile.exists()) {
FileObject tempFileObject = FileUtil.toFileObject(writeFile);
try {
bufferedOutputStream.close();
} catch (IOException ex1) {
tempFileObject.delete();
} catch (IOException ex) {
}
}
if (useTempFile && writeFile != null) {
writeFile.delete();
}
Progress.finish(progressTicket);
}
private void writeProject(GephiWriter gephiWriter, BufferedOutputStream bufferedOutputStream, ZipOutputStream zipOut) throws Exception {
XMLStreamWriter writer = null;
//Write Project file
zipOut.putNextEntry(new ZipEntry("Project_xml"));
try {
//Create Writer and write project
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.FALSE);
writer = outputFactory.createXMLStreamWriter(bufferedOutputStream, "UTF-8");
gephiWriter.writeProject(writer, project);
} finally {
if (writer != null) {
writer.close();
}
}
//Close Project file
zipOut.closeEntry();
}
private void writeWorkspace(Workspace workspace, GephiWriter gephiWriter, BufferedOutputStream bufferedOutputStream, ZipOutputStream zipOut) throws Exception {
//Write Project file
zipOut.putNextEntry(new ZipEntry("Workspace" + workspace.getId() + "_xml"));
XMLStreamWriter writer = null;
try {
//Create Writer and write project
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.FALSE);
writer = outputFactory.createXMLStreamWriter(bufferedOutputStream, "UTF-8");
gephiWriter.writeWorkspace(writer, workspace);
} finally {
if (writer != null) {
writer.close();
}
throw new GephiFormatException(GephiWriter.class, ex);
}
//Close Project file
zipOut.closeEntry();
}
@Override
......
package org.gephi.project.io;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
/**
* {@link FilterReader} to skip invalid xml version 1.0 characters. Valid
* Unicode chars for xml version 1.0 according to http://www.w3.org/TR/xml are
* #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD], [#x10000-#x10FFFF] . In
* other words - any Unicode character, excluding the surrogate blocks, FFFE,
* and FFFF.
* <p>
* More details on the <a
* href="http://info.tsachev.org/2009/05/skipping-invalid-xml-character-with.html">blog</a>
*/
public class Xml10FilterReader extends FilterReader {
/**
* Creates filter reader which skips invalid xml characters.
*
* @param in original reader
*/
public Xml10FilterReader(Reader in) {
super(in);
}
/**
* Every overload of {@link Reader#read()} method delegates to this one so
* it is enough to override only this one. <br />
* To skip invalid characters this method shifts only valid chars to left
* and returns decreased value of the original read method. So after last
* valid character there will be some unused chars in the buffer.
*
* @return Number of read valid characters or <code>-1</code> if end of the
* underling reader was reached.
*/
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int read = super.read(cbuf, off, len);
/*
* If read chars are -1 then we have reach the end of the reader.
*/
if (read == -1) {
return -1;
}
/*
* pos will show the index where chars should be moved if there are gaps
* from invalid characters.
*/
int pos = off - 1;
for (int readPos = off; readPos < off + read; readPos++) {
if (XMLChar.isValid(cbuf[readPos])) {
pos++;
} else {
continue;
}
/*
* If there is gap(s) move current char to its position.
*/
if (pos < readPos) {
cbuf[pos] = cbuf[readPos];
}
}
/*
* Number of read valid characters.
*/
return pos - off + 1;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册