/* * Lokomo OneCMDB - An Open Source Software for Configuration * Management of Datacenter Resources * * Copyright (C) 2006 Lokomo Systems AB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via * paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33 * Danderyd, Sweden. * */ package org.onecmdb.ui.gwt.desktop.server.service.content; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.List; import java.util.Properties; import org.apache.xmlbeans.impl.common.IOUtil; import org.onecmdb.core.internal.authorization.RBACSession; import org.onecmdb.ui.gwt.desktop.client.service.CMDBRPCException; import org.onecmdb.ui.gwt.desktop.client.service.content.ContentData; import org.onecmdb.ui.gwt.desktop.client.service.content.ContentFile; import org.onecmdb.ui.gwt.desktop.client.service.content.ContentFolder; import org.onecmdb.ui.gwt.desktop.client.service.content.IContentService; import org.onecmdb.ui.gwt.desktop.server.service.CMDBRPCHandler; import org.onecmdb.ui.gwt.desktop.server.service.ServiceLocator; import com.google.gwt.user.server.rpc.RemoteServiceServlet; public class ContentServiceImpl extends RemoteServiceServlet implements IContentService { private static final String META_DATA = "content.meta"; private File root; public ContentServiceImpl() { // Default root. setRoot(ContentParserFactory.get().getRootPath().getPath()); ServiceLocator.registerService(IContentService.class, this); } public ContentServiceImpl(String root) { setRoot(root); } protected RBACSession getRBACSession(String token) { return(null); } private void validateDelete(String token) { } private void validateRead(String token) { } private void validateWrite(String token) { } private File getRoot() { return(this.root); } private void setRoot(String path) { this.root = new File(path); } /** * ==================================================================== * Interface methods goes below. * * */ public boolean delete(String token, ContentData parent) { validateDelete(token); File f = new File(getRoot(), parent.getPath()); return(f.delete()); } public String get(String token, ContentData parent, String enc) { validateRead(token); File f = new File(getRoot(), parent.getPath()); try { FileInputStream fis = new FileInputStream(f); int x= fis.available(); byte b[]= new byte[x]; fis.read(b); String content = ""; if (enc != null) { content = new String(b, enc); } else { content = new String(b); } return(content); } catch (Throwable t) { return(t.toString()); } } public String get(String token, ContentData parent) { return(get(token,parent,null)); } public boolean move(String token, ContentData fromData, ContentData toData) { File from = locateFile(fromData); File to = locateFile(toData); return(from.renameTo(to)); } public boolean create(String token, ContentData data) { if (data instanceof ContentFolder) { File newFolder = locateFile(data); boolean b = newFolder.mkdirs(); return(b); } if (data instanceof ContentFile) { File newFile = locateFile(data); if (!newFile.getParentFile().exists()) { newFile.getParentFile().mkdirs(); } boolean b = false; try { b = newFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } return(b); } return(false); } public boolean put(String token, ContentData content, String enc, String data) { validateWrite(token); File file = locateFile(content); /* if (!file.exists()) { throw new IllegalArgumentException("Can't find file " + content.getName()); } */ if (file.isDirectory()) { throw new IllegalArgumentException("Is not a file " + content.getName()); } OutputStreamWriter out = null; try { if (enc != null) { out = new OutputStreamWriter(new FileOutputStream(file), enc); } else { out = new OutputStreamWriter(new FileOutputStream(file)); } //out = new FileOutputStream(file); out.write(data, 0, data.length()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); throw new IllegalArgumentException("Can't write to file " + content.getName(), e); } finally { try { if (out != null) { out.close(); } } catch (IOException e) { // Ignore } } return(true); } public boolean put(String token, ContentData content, String data) { return(put(token, content, null, data)); } public List<? extends ContentData> list(String token, ContentData parent) { validateRead(token); File root = locateFile(parent); File files[] = root.listFiles(); List<ContentData> result = new ArrayList<ContentData>(); if (files == null) { return(result); } // Check for a property file. Properties meta = getMetaData(root); for (int i = 0; i < files.length; i++) { File f = files[i]; if (f.getName().equals(META_DATA)) { //continue; } ContentData cData = null; if (f.isDirectory()) { cData = new ContentFolder(); } else { cData = new ContentFile(); } cData.setPath(f.getPath().substring(getRoot().getPath().length())); cData = stat(cData); cData = updateMetaData(cData, meta); result.add(cData); } return(result); } public ContentData stat(ContentData data) { File f = locateFile(data); data.setExists(f.exists()); data.setLastModified(f.lastModified()); data.setSize(f.length()); data.setDirectory(f.isDirectory()); data.setName(f.getName()); return(data); } public ContentFolder mkdir(String token, ContentData parent, ContentData child) throws CMDBRPCException { File dir = locateFile(parent); if (!dir.exists()) { throw new CMDBRPCException("mkdir Error:", "Parent " + parent.getPath() + " don't exists", ""); } if (!dir.isDirectory()) { throw new CMDBRPCException("mkdir Error:", "Parent " + parent.getPath() + " is not a directory", ""); } ContentFolder newFolder = new ContentFolder(); newFolder.setPath(parent.getPath() + "/" + child.getPath()); File newDir = locateFile(newFolder); boolean result = newDir.mkdirs(); if (!result) { throw new CMDBRPCException("mkdir Error:", "Can't create dir " + newFolder.getPath(), ""); } return(newFolder); } public ContentFolder mkdir(String token, ContentData folder) throws CMDBRPCException { File dir = locateFile(folder); if (dir.exists()){ throw new CMDBRPCException("mkdir Error:", "Folder " + folder.getPath() + " exists", ""); } File newDir = locateFile(folder); boolean result = newDir.mkdirs(); if (!result) { throw new CMDBRPCException("mkdir Error:", "Can't create dir " + folder.getPath(), ""); } return(new ContentFolder(folder.getPath())); } /** * End of Interface Methods. * ==================================================================== * Private functions here.... * * */ private Properties getMetaData(File root) { if (root == null) { return(null); } File meta = new File(root, META_DATA); // Search upwards... if (!meta.exists()) { return(getMetaData(root.getParentFile())); } Properties p = new Properties(); if (meta.exists()) { InputStream in = null; try { in = new FileInputStream(meta); p.loadFromXML(in); } catch (Throwable t) { // Can't load meta data } finally { if (in != null) { try { in.close(); } catch (Throwable t) { // Silent Ignore... } } } } return(p); } private File locateFile(ContentData parent) { if (parent == null) { return(getRoot()); } String path = parent.getPath(); if (path == null || path.length() == 0) { return(getRoot()); } File f = new File(getRoot(), path); // Validate that the path is not above getRoot(); try { String realPath = f.getCanonicalPath(); String rootPath = getRoot().getCanonicalPath(); if (!realPath.startsWith(rootPath)) { System.out.println("OutOfBound: root<" + rootPath + "> path<" + realPath + ">"); //throw new IllegalArgumentException("Illegal Path!!"); } return(f); } catch (IOException e) { throw new IllegalArgumentException("Error", e); } } public boolean exists(ContentData data) { File f = locateFile(data); return(f.exists()); } public ContentData updateMetaData(ContentData data) { File f = locateFile(data); return(updateMetaData(data, getMetaData(f.getParentFile()))); } public ContentData updateMetaData(ContentData data, Properties p) { if (p == null) { return(data); } for (Enumeration<?> keys = p.propertyNames(); keys.hasMoreElements(); ) { String key = (String) keys.nextElement(); data.set(key, p.getProperty(key)); } return(data); } /** * Copy content. * If the source is a directory it will do a deep copy. * If the traget exists and override is false then an exception * will be generated. * @throws CMDBRPCExceptionException * */ public boolean copy(String token, ContentData source, ContentData target, boolean override) throws CMDBRPCException { System.out.println("COPY '" + source.getPath() + "' --> '" + target.getPath() + "'"); stat(target); if (target.isExists() && !override) { throw new CMDBRPCException("Copy Error", "Target " + target.getPath() + " exists.., will not copy", ""); } stat(source); if (!source.isExists()) { throw new CMDBRPCException("Copy Error", "Source " + target.getPath() + " not found!", ""); } // Create folder if (source.isDirectory()) { target = mkdir(token, target); ContentData childTarget = target; // Create childTarget... String sourceFolder = source.getLastPathEntry(); // If Source folder ends with / we will not use its name /* if (sourceFolder == null || sourceFolder.length() == 0) { ContentData parent = source.getParent(); childTarget = new ContentFolder(target.getPath() + "/" + parent.getLastPathEntry()); } */ List<? extends ContentData> children = list(token, source); for (ContentData child : children) { ContentData targetChild = new ContentFolder(childTarget.getPath() + "/" + child.getLastPathEntry()); copy(token, child, targetChild, override); } return(true); } // Copy the file. try { copyFile(source, target); } catch (IOException e) { throw new CMDBRPCException("Copy Error", "Coping file " + source.getPath() + " to " + target.getPath(), CMDBRPCHandler.getStackTrace(e)); } return true; } protected void copyFile(ContentData source, ContentData target) throws IOException { File s = locateFile(source); File t = locateFile(target); if (t.isDirectory()) { t = new File(t, source.getLastPathEntry()); } OutputStream out = null; InputStream in = null; try { out = new FileOutputStream(t); in = new FileInputStream(s); IOUtil.copyCompletely(in, out); } finally { if (in != null) { try { in.close(); } catch (IOException e) { // Ignore! } } if (out != null) { try { out.close(); } catch (IOException e) { // Ignore! } } } } public static void main(String argv[]) { ContentServiceImpl svc = new ContentServiceImpl("d:/tmp/contentdata"); ContentData src = new ContentFolder("Source/Default/"); ContentData dest = new ContentFolder("Target/new"); try { svc.copy("", src, dest, false); } catch (CMDBRPCException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }