blob: d71f74bed55827a216781ed5f26b73b60b7915ff [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004-2008 Andras Schmidt, Andras Balogh, Istvan Rath and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andras Schmidt, Andras Balogh, Istvan Rath - initial API and implementation
*******************************************************************************/
package org.eclipse.viatra2.buffers;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.viatra2.core.IModelSpace;
/**
* Buffer store singleton to manage output buffers for VIATRA2.
* @author Istvan Rath
*
*/
public class BufferStore {
private static BufferStore _instance = new BufferStore();
private HashMap<IModelSpace, HashMap<String, StringWriter>> core_buffers = new HashMap<IModelSpace, HashMap<String, StringWriter>>();
private HashMap<IModelSpace, HashMap<String, FileWriter>> file_buffers = new HashMap<IModelSpace, HashMap<String, FileWriter>>();
public static synchronized void removeBuffer(IModelSpace m, String pURI) {
String key = pURI;
HashMap<String, StringWriter> target = _instance.core_buffers.get(m);
if (target != null) {
target.remove(key);
}
HashMap<String, FileWriter> _target = _instance.file_buffers.get(m);
if (_target != null) {
_target.remove(key);
}
}
public static synchronized void removeFileBuffers(IModelSpace m) {
_instance.file_buffers.remove(m);
// refresh workspace
try {
ResourcesPlugin.getWorkspace().getRoot().refreshLocal(
IResource.DEPTH_INFINITE, new NullProgressMonitor());
} catch (CoreException e) {
m.getFramework().getLogger().fatal(e.getMessage());
}
}
/**
* Clear operation is only supported for "core://" buffers.
* @param m
* @param pURI
* @throws URISyntaxException
*/
public static synchronized void clearBuffer(IModelSpace m, String pURI) throws URISyntaxException
{
// parse URI
URI uri = new URI(pURI);
String key = pURI;
if ("core".equals(uri.getScheme())) {
// write to in-memory buffer
HashMap<String, StringWriter> target = _instance.core_buffers
.get(m);
if (target == null) {
target = new HashMap<String, StringWriter>();
_instance.core_buffers.put(m, target);
}
StringWriter ret = target.get(key);
if (ret == null) {
// designated buffer does not exist
// do nothing
}
else
{
ret.getBuffer().delete(0, ret.getBuffer().length());
//ret = new StringWriter(); // this causes a problem if there
// is a state reference at VTCL level (see #186)
//target.put(key, ret);
}
} else if ("file".equals(uri.getScheme()))
{
HashMap<String, FileWriter> target = _instance.file_buffers.get(m);
if (target==null) {
target = new HashMap<String, FileWriter>();
_instance.file_buffers.put(m, target);
}
FileWriter ret = target.get(key);
if (ret == null)
{
// do nothing
}
else {
String path = uri.getAuthority() + uri.getPath();
IFile ifile = ResourcesPlugin.getWorkspace().getRoot().getFile(
new Path(path));
if (ifile.exists())
{
// only do something if the file exists
try {
ifile.setContents(new StringBufferInputStream(""), true, false, null);
//ifile.delete(true, null);
//ifile.create(new StringBufferInputStream(""), true, null);
/*
FileWriter fw = new FileWriter(
new File(ifile.getLocation().toOSString()), false);
fw.write("");
fw.flush();
fw.close();
*/
}
catch (Exception e) {
m.getFramework().getLogger().error("Error encountered while attempting to clear file buffer: "+e.getMessage());
m.getFramework().getLogger().printStackTrace(e);
}
}
}
} else if("os".equals(uri.getScheme())) {
HashMap<String, FileWriter> target = _instance.file_buffers.get(m);
if (target==null) {
target = new HashMap<String, FileWriter>();
_instance.file_buffers.put(m, target);
}
FileWriter ret = target.get(key);
if (ret == null)
{
// do nothing
}
else {
String path = uri.getAuthority() + uri.getPath();
File f = new File(path);
if(f.exists()) {
FileWriter fw;
try {
fw = new FileWriter(f, false);
fw.write("");
fw.flush();
fw.close();
} catch (Exception e) {
m.getFramework().getLogger().error("Error encountered while attempting to clear os buffer: "+e.getMessage());
m.getFramework().getLogger().printStackTrace(e);
}
}
}
}
}
/**
* Retrieves a reference to a <code>java.io.Writer</code> which can be used as a VIATRA2
* output buffer.
* @param m
* @param pURI
* @return
* @throws URISyntaxException
* @throws IOException
*/
public static synchronized Writer getBuffer(IModelSpace m, String pURI, boolean append)
throws URISyntaxException, IOException {
// parse URI
URI uri = new URI(pURI);
String key = pURI;
if ("core".equals(uri.getScheme())) {
// write to in-memory buffer
HashMap<String, StringWriter> target = _instance.core_buffers
.get(m);
if (target == null) {
target = new HashMap<String, StringWriter>();
_instance.core_buffers.put(m, target);
}
StringWriter ret = target.get(key);
if (ret == null) {
ret = new StringWriter();
target.put(key, ret);
notifyAdded(key);
}
return ret;
} else if ("file".equals(uri.getScheme())) {
// write to workspace-relative file
String path = uri.getAuthority() + uri.getPath();
// check whether the path exists
// if not, create projects
// ResourcesPlugin.getWorkspace().newProjectDescription("teszt");
HashMap<String, FileWriter> target = _instance.file_buffers.get(m);
if (target == null) {
target = new HashMap<String, FileWriter>();
_instance.file_buffers.put(m, target);
}
FileWriter ret = target.get(key);
if (ret == null) {
IFile ifile = ResourcesPlugin.getWorkspace().getRoot().getFile(
new Path(path));
IProject p = ResourcesPlugin.getWorkspace().getRoot()
.getProject(uri.getAuthority());
IProgressMonitor mon = new NullProgressMonitor();
try {
if (!p.exists()) {
p.create(mon);
}
p.open(mon);
} catch (CoreException cex) {
throw new IOException(
"Target project cannot be created/opened");
}
// make sure project-relative path exists
try {
String[] segments = uri.getPath().split("/");
if (segments.length > 2) // first segment is always "" due
// to path beginning with '/'
{
// there is at least one directory below the project
// root
IFolder curr = null;
for (int i = 1; i < segments.length - 1; i++) // last
// segment
// will
// always
// be
// the
// file
// name
{
if (curr == null)
curr = p.getFolder(segments[i]);
else
curr = curr.getFolder(segments[i]);
if (!curr.exists())
curr.create(true, true, mon);
}
}
} catch (CoreException cex) {
throw new IOException(
"Target folder structure cannot be created");
}
// open writer to the file
ret = new FileWriter(
new File(ifile.getLocation().toOSString()), append);
target.put(key, ret);
// notifyAdded(key);
}
return ret;
} else if("os".equals(uri.getScheme())) {
// write to workspace-relative file
String path = uri.getAuthority() + uri.getPath();
// check whether the path exists
// if not, create projects
// ResourcesPlugin.getWorkspace().newProjectDescription("teszt");
HashMap<String, FileWriter> target = _instance.file_buffers.get(m);
if (target == null) {
target = new HashMap<String, FileWriter>();
_instance.file_buffers.put(m, target);
}
FileWriter ret = target.get(key);
if (ret == null) {
// absolute path should be correct...
File f = new File(path);
if(!f.exists()) {
String par = f.getParent();
File parf = new File(par);
if(!parf.exists()) {
parf.mkdirs();
}
f.createNewFile();
}
ret = new FileWriter(f, append);
target.put(key, ret);
}
return ret;
}
return null;
}
public static synchronized Writer getBuffer(IModelSpace m, String pURI) throws URISyntaxException, IOException
{
return getBuffer(m, pURI, true);
}
public static synchronized Set<Map.Entry<String, StringWriter>> getAllCoreBuffers(
IModelSpace m) {
if (_instance.core_buffers.get(m) != null)
return _instance.core_buffers.get(m).entrySet();
else
return null;
}
public static synchronized Set<Map.Entry<String, FileWriter>> getAllFileBuffers(
IModelSpace m) {
if (_instance.file_buffers.get(m) != null)
return _instance.file_buffers.get(m).entrySet();
else
return null;
}
private List<IBufferStoreListener> listeners = new ArrayList<IBufferStoreListener>();
public synchronized static void addListener(IBufferStoreListener l) {
_instance.listeners.add(l);
}
public synchronized static void removeListener(IBufferStoreListener l) {
_instance.listeners.remove(l);
}
private static void notifyAdded(String key) {
for (IBufferStoreListener l : _instance.listeners)
l.bufferAdded(key);
}
private static void notifyRemoved(String key) {
for (IBufferStoreListener l : _instance.listeners)
l.bufferRemoved(key);
}
}