| /******************************************************************************* |
| * 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); |
| } |
| |
| } |