Separate project zip file into multiple entries, one for the project and one for each workspace. Improve error handling.
Esse commit está contido em:
+41
-50
@@ -1,43 +1,43 @@
|
||||
/*
|
||||
Copyright 2008-2010 Gephi
|
||||
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
|
||||
Website : http://www.gephi.org
|
||||
Copyright 2008-2010 Gephi
|
||||
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
|
||||
Website : http://www.gephi.org
|
||||
|
||||
This file is part of Gephi.
|
||||
This file is part of Gephi.
|
||||
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
||||
|
||||
Copyright 2011 Gephi Consortium. All rights reserved.
|
||||
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]"
|
||||
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.
|
||||
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):
|
||||
Contributor(s):
|
||||
|
||||
Portions Copyrighted 2011 Gephi Consortium.
|
||||
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();
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
/*
|
||||
Copyright 2008-2010 Gephi
|
||||
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
|
||||
Website : http://www.gephi.org
|
||||
Copyright 2008-2010 Gephi
|
||||
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
|
||||
Website : http://www.gephi.org
|
||||
|
||||
This file is part of Gephi.
|
||||
This file is part of Gephi.
|
||||
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
||||
|
||||
Copyright 2011 Gephi Consortium. All rights reserved.
|
||||
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]"
|
||||
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.
|
||||
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):
|
||||
Contributor(s):
|
||||
|
||||
Portions Copyrighted 2011 Gephi Consortium.
|
||||
*/
|
||||
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,41 +106,68 @@ 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"));
|
||||
}
|
||||
|
||||
workspace = project.getLookup().lookup(WorkspaceProviderImpl.class).newWorkspace(workspaceId);
|
||||
WorkspaceInformationImpl info = workspace.getLookup().lookup(WorkspaceInformationImpl.class);
|
||||
|
||||
//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();
|
||||
}
|
||||
|
||||
//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.");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorkspaceImpl workspace = project.getLookup().lookup(WorkspaceProviderImpl.class).newWorkspace(workspaceId);
|
||||
WorkspaceInformationImpl info = workspace.getLookup().lookup(WorkspaceInformationImpl.class);
|
||||
|
||||
//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();
|
||||
}
|
||||
|
||||
//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.");
|
||||
}
|
||||
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;
|
||||
|
||||
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 {
|
||||
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");
|
||||
|
||||
//Append
|
||||
writer.writeEndElement();
|
||||
writer.writeEndElement();
|
||||
}
|
||||
private static final String VERSION = "0.9";
|
||||
|
||||
public void writeProject(XMLStreamWriter writer, Project project) throws Exception {
|
||||
writer.writeStartDocument("UTF-8", "1.0");
|
||||
writer.writeStartElement("projectFile");
|
||||
|
||||
writeHeader(writer);
|
||||
|
||||
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() {
|
||||
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];
|
||||
}
|
||||
Progress.start(progressTicket);
|
||||
Progress.setDisplayName(progressTicket, NbBundle.getMessage(LoadTask.class, "LoadTask.name"));
|
||||
|
||||
try {
|
||||
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);
|
||||
isReader = new InputStreamReader(inputStream, "UTF-8");
|
||||
filterReader = new Xml10FilterReader(isReader);
|
||||
reader = inputFactory.createXMLStreamReader(filterReader);
|
||||
|
||||
if (!cancel) {
|
||||
ProjectControllerImpl projectController = Lookup.getDefault().lookup(ProjectControllerImpl.class);
|
||||
ProjectsImpl projects = projectController.getProjects();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//GephiReader
|
||||
gephiReader = new GephiReader();
|
||||
Project project = gephiReader.readAll(reader, projects);
|
||||
project.getLookup().lookup(ProjectInformationImpl.class).setFile(file);
|
||||
|
||||
//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);
|
||||
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.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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Stream
|
||||
int zipLevel = NbPreferences.forModule(SaveTask.class).getInt(ZIP_LEVEL_PREFERENCE, 9);
|
||||
FileOutputStream outputStream = new FileOutputStream(writeFile);
|
||||
zipOut = new ZipOutputStream(outputStream);
|
||||
zipOut.setLevel(zipLevel);
|
||||
|
||||
zipOut.putNextEntry(new ZipEntry("Project"));
|
||||
gephiWriter = new GephiWriter();
|
||||
|
||||
//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) {
|
||||
if (ex instanceof GephiFormatException) {
|
||||
throw (GephiFormatException) ex;
|
||||
}
|
||||
throw new GephiFormatException(SaveTask.class, ex);
|
||||
} finally {
|
||||
if (writeFile != null && writeFile.exists()) {
|
||||
FileObject tempFileObject = FileUtil.toFileObject(writeFile);
|
||||
try {
|
||||
zipOut.close();
|
||||
} catch (IOException ex1) {
|
||||
tempFileObject.delete();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bufferedOutputStream != null) {
|
||||
try {
|
||||
bufferedOutputStream.close();
|
||||
} catch (IOException ex1) {
|
||||
}
|
||||
}
|
||||
if (useTempFile && writeFile != null) {
|
||||
writeFile.delete();
|
||||
}
|
||||
throw new GephiFormatException(GephiWriter.class, ex);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
//Close Project file
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Referência em uma Nova Issue
Bloquear um usuário