/* * $Id: FileSystemCopyServiceBean.java,v 1.10 2007/08/17 13:42:00 valdas Exp $ * Created on 2.11.2004 * * Copyright (C) 2004 Idega Software hf. All Rights Reserved. * * This software is the proprietary information of Idega hf. * Use is subject to license terms. */ package com.idega.slide.business; import java.io.IOException; import java.sql.SQLException; import java.util.Collection; import java.util.Iterator; import java.util.StringTokenizer; import javax.ejb.EJBException; import javax.ejb.FinderException; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpURL; import org.apache.webdav.lib.WebdavResource; import com.idega.business.IBOLookupException; import com.idega.business.IBORuntimeException; import com.idega.business.IBOServiceBean; import com.idega.core.builder.data.ICPage; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileHome; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.data.IDOStoreException; import com.idega.slide.data.SlideFile; import com.idega.slide.data.SlideFileHome; import com.idega.util.CoreConstants; import com.idega.util.database.ConnectionBroker; /** * * Last modified: $Date: 2007/08/17 13:42:00 $ by $Author: valdas $ * * @author <a href="mailto:aron@idega.com">aron</a> * @version $Revision: 1.10 $ */ public class FileSystemCopyServiceBean extends IBOServiceBean implements FileSystemCopyService{ private SlideFileHome fileHome = null; private ICFileHome icFileHome = null; private WebdavResource webdavResource = null; private String path = null; private HttpURL httpURL = null; private boolean overwrite = true; private String pageFolderName = "Pages"; private String templateFolderName = "Templates"; private String publicFolderName = "Public"; private String userFolderName = "Users"; private SlideFileHome getFileHome(){ try { if(this.fileHome==null) { this.fileHome = (SlideFileHome)IDOLookup.getHome(SlideFile.class); } return this.fileHome; } catch (IDOLookupException e) { throw new IBORuntimeException(e); } } private ICFileHome getICFileHome(){ try { if(this.icFileHome==null) { this.icFileHome = (ICFileHome)IDOLookup.getHome(ICFile.class); } return this.icFileHome; } catch (IDOLookupException e) { throw new IBORuntimeException(e); } } public void run() throws Exception{ this.httpURL = getService().getWebdavServerURL(); if(this.httpURL!=null){ this.httpURL.getEscapedURI(); connect(); copyPageFiles(); copyGroupFiles(); copyMediaSystem(); copyLeftovers(); disconnect(); } else{ log("Filesystem could not be copied to Slide, no server url was provided"); } } private void copyPageFiles(){ try { ICPage startPage = getIWApplicationContext().getDomain().getStartPage(); String folder = this.pageFolderName; checkAndCreateFolder(folder); copy2(folder,startPage.getFile(),"ibxml"); Collection childs = startPage.getChildren(); String subFolder = folder+"/"+startPage.getName(); checkAndCreateFolder(subFolder); if(childs!=null) { copyPages(subFolder,childs); } ICPage templatePage = getIWApplicationContext().getDomain().getStartTemplate(); folder = this.templateFolderName; checkAndCreateFolder(folder); copy2(folder,templatePage.getFile(),"ibxml"); childs = templatePage.getChildren(); subFolder = folder+"/"+templatePage.getName(); checkAndCreateFolder(subFolder); if(childs!=null) { copyPages(subFolder,childs); } } catch (IDOLookupException e) { throw new IBORuntimeException(e); } catch (Exception e) { throw new IBORuntimeException(e); } } public void copyPages(String folder,Collection pages)throws Exception{ for (Iterator iter = pages.iterator(); iter.hasNext();) { ICPage element = (ICPage) iter.next(); ICFile file = element.getFile(); if(file.getName()==null) { file.setName(element.getName()); } copy2(folder,file,"ibxml"); if(element.getChildCount()>0){ Collection childs = element.getChildren(); checkAndCreateFolder(folder+"/"+element.getName()); copyPages(folder+"/"+element.getName(),childs); } } } private void copyGroupFiles(){ String sql = "select user_login,ic_group_id,home_folder_id" +" from ic_login l, ic_group g " +" where l.ic_user_id = g.ic_group_id " +"and g.home_folder_id is not null"; java.sql.Connection conn = null; java.sql.Statement stmt = null; java.sql.ResultSet rs = null; try { conn = ConnectionBroker.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery(sql); while(rs.next()){ String username = rs.getString(1); Integer fileID = new Integer(rs.getInt(3)); ICFile root = getICFileHome().findByPrimaryKey(fileID); if(root.isFolder()){ Collection children = getICFileHome().findChildren(root,null,null,null); copy(this.userFolderName+"/"+username,children); } else{ copy(this.userFolderName+"/"+username,root); } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FinderException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ if(rs!=null){ try { rs.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } if(stmt !=null){ try { stmt.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } if(conn!=null){ ConnectionBroker.freeConnection(conn); } } } private void copyMediaSystem(){ try { ICFile root = getICFileHome().findRootFolder(); Collection children = getICFileHome().findChildren(root,null,null,null); copy(this.publicFolderName,children); } catch (IDOLookupException e) { throw new IBORuntimeException(e); } catch (FinderException e) { throw new IBORuntimeException(e); } catch (Exception e) { throw new IBORuntimeException(e); } } private void copyLeftovers(){ // lets copy everything still not copied, and not folders String sql = "select ic_file_id from ic_file where ext_url is null and mime_type != 'application/vnd.iw-folder'"; java.sql.Connection conn = null; java.sql.Statement stmt = null; java.sql.ResultSet rs = null; try { conn = ConnectionBroker.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery(sql); while(rs.next()){ Integer fileID = new Integer(rs.getInt(1)); ICFile root = getFileHome().findByPrimaryKey(fileID); /* skip the folders if(root.isFolder()){ Collection children = getICFileHome().findChildren(root,null,null,null); copy(publicFolderName+"/attic",children); } else*/{ copy(this.userFolderName+"/attic",root); } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FinderException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ if(rs!=null){ try { rs.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } if(stmt !=null){ try { stmt.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } if(conn!=null){ ConnectionBroker.freeConnection(conn); } } } private void connect(){ /* if (!uri.endsWith("/") && !uri.endsWith("\\")) { // append / to the path uri+="/"; } */ //System.out.println("connect " + uri); try { //httpURL = uriToHttpURL(uri); // httpURL.setUserinfo("root","root"); if (this.webdavResource == null) { this.webdavResource = getService().getWebdavExternalResourceAuthenticatedAsRoot(); //webdavResource.setDebug(Integer.MAX_VALUE); // is not a collection? if (!this.webdavResource.getResourceType().isCollection()) { this.webdavResource = null; this.httpURL = null; //System.out.println("Error: " + uri + " is not a collection! Use open/connect only for collections!"); } } else { this.webdavResource.close(); // webdavResource.setHttpURL(httpURL); this.webdavResource = getService().getWebdavExternalResourceAuthenticatedAsRoot(); } setPath(this.webdavResource.getPath()+CoreConstants.PATH_FILES_ROOT); } catch (HttpException we) { System.out.print("HttpException.getReasonCode(): "+ we.getReasonCode()); if (we.getReasonCode() == HttpStatus.SC_UNAUTHORIZED) { try { String userName = "root"; if ((userName==null) || (userName.length()==0)) { disconnect(); return; } userName = userName.trim(); String password = "root"; if (password != null) { password= password.trim(); } try { if (this.webdavResource != null) { this.webdavResource.close(); } } catch (IOException e) { } finally { this.httpURL = null; this.webdavResource = null; } //httpURL = uriToHttpURL(uri); // It should be used like this way. this.httpURL.setUserinfo(userName, password); this.webdavResource = new WebdavResource(this.httpURL); //webdavResource.setDebug(Integer.MAX_VALUE); setPath(this.webdavResource.getPath()); if (!this.webdavResource.getResourceType().isCollection()) { this.webdavResource = null; this.httpURL = null; System.out.println("Error: " + this.httpURL.getURI() + " is not a collection! Use open/connect only for collections!"); } } catch (Exception ex) { handleException(ex); this.httpURL = null; this.webdavResource = null; } } else { handleException(we); this.httpURL = null; this.webdavResource = null; } } catch (Exception ex) { handleException(ex); this.webdavResource = null; this.httpURL = null; } } void disconnect() { System.out.println("disconnect"); try { this.webdavResource.close(); } catch (IOException e) { } finally { // Make sure the connection closed. this.httpURL = null; this.webdavResource = null; } } private void handleException(Exception ex) { if (ex instanceof HttpException) { if (((HttpException) ex).getReasonCode() == HttpStatus.SC_METHOD_NOT_ALLOWED) { System.out.println("Warning: Not WebDAV-enabled?"); } else if (((HttpException) ex).getReasonCode() == HttpStatus.SC_UNAUTHORIZED) { System.out.println("Warning: Unauthorized"); } else { System.out.println("Warning: " + ex.getMessage()); } } else if (ex instanceof IOException) { System.out.println("Error: " + ex.getMessage()); } else { System.out.println("Fatal Error: " + ex.getMessage()); ex.printStackTrace(System.out); System.out.println("Please, email to slide-user@jakarta.apache.org"); } } public void copy(String folder,Collection files)throws Exception{ for (Iterator iter = files.iterator(); iter.hasNext();) { ICFile element = (ICFile) iter.next(); if(element.isFolder()){ Collection childs = getICFileHome().findChildren(element,null,null,null); checkAndCreateFolder(folder); copy(folder+"/"+element.getName(),childs); } else{ checkAndCreateFolder(folder); copy2(folder,element,null); } } } public void checkAndCreateFolder(String folder){ try { this.webdavResource.setPath(folder); if(!this.webdavResource.exists()) { mkcol(folder); } } catch (HttpException e) { mkcol(folder); createFolderIfNotExists(folder); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void createFolderIfNotExists(String folderPath){ int index = folderPath.indexOf("/",1); while(index>0){ String path = folderPath.substring(0,index+1); //System.out.println(path); mkcol(path); index = folderPath.indexOf("/",index+1); } } void put(ICFile file, String path) { try { String dest = getRemoteTargetFileName( file.getName(), path); String currentPath = this.webdavResource.getPath(); try { this.webdavResource.setPath(dest); if (this.webdavResource.exists()) { System.out.print("Aleady exists. "); } this.webdavResource.setPath(currentPath); } catch (Exception ex) { } if(this.overwrite){ System.out.print("Uploading '" + file.getName() + "' to '" + dest + "' "); if (this.webdavResource.putMethod(dest, file.getFileValue())) { updateFile(file, dest); System.out.println("succeeded."); } else { System.out.println("failed."); System.out.println(this.webdavResource.getStatusMessage()); } } } catch (Exception ex) { handleException(ex); } } private void updateFile(ICFile file, String path){ try { SlideFile slideFile = getFileHome().findByPrimaryKey(file.getPrimaryKey()); slideFile.setExternalURL(path); slideFile.store(); } catch (IDOStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (EJBException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FinderException e) { // TODO Auto-generated catch block e.printStackTrace(); } } void mkcol(String path) { try { path = checkUri(path); System.out.print("Making '" + path + "' collection: "); if (this.webdavResource.mkcolMethod(path)) { System.out.println("succeeded."); } else { System.out.println("failed."); System.out.println(this.webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void delete(String path) { try { path = checkUri(path); System.out.print("Deleting '" + path + "': "); if (this.webdavResource.deleteMethod(path)) { System.out.println("succeeded."); } else { System.out.println("failed."); System.out.println(this.webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } private void copy2(String folder,ICFile file,String extension)throws Exception{ //delete(folder); //mkcol(folder); String fileName = file.getName(); if(extension!=null && !fileName.endsWith(extension)){ fileName += "."+extension; } put(file,folder+"/"+fileName); } private void copy(String folder, ICFile file)throws Exception{ /* System.out.println("Moving "+file.getName()+" in folder "+folder); WebdavFile rootFile = getService().getWebdavFile(); File[] files = rootFile.listFiles(); for (int i = 0; i < files.length; i++) { System.out.println(files[i]); } String rootpath = rootFile.getAbsolutePath(); WebdavFile filefolder = new WebdavFile(rootFile,"files"); WebdavFile newfolder = new WebdavFile(filefolder,"myFolder"); if(!newfolder.exists()) newfolder.mkdir(); files = rootFile.listFiles(); for (int i = 0; i < files.length; i++) { System.out.println(files[i]); } */ copy2(folder, file, null); } protected WebdavResource getResource(String path)throws Exception{ IWSlideService service = getService(); return service.getWebdavResourceAuthenticatedAsRoot(path); } public IWSlideService getService(){ try { return (IWSlideService) getServiceInstance(IWSlideService.class); } catch (IBOLookupException e) { throw new IBORuntimeException(e); } } private String getRemoteTargetFileName(String filename, String path) { String srcPathName = null; String target = null; // get traget filename from last portion of filename StringTokenizer st = new StringTokenizer(filename, "/\\"); while (st.hasMoreTokens()) { srcPathName = st.nextToken(); } try { if (path != null) { target = checkUri(path); // check is path a collection ? String currentPath = this.webdavResource.getPath(); this.webdavResource.setPath(target); if (this.webdavResource.exists()) { if (this.webdavResource.isCollection()) { target += "/" + srcPathName; } } this.webdavResource.setPath(currentPath); } else { target = checkUri(getPath() + "/" + srcPathName); } } catch (Exception ex) { } return target; } private String checkUri(String uri) throws IOException { if (this.webdavResource == null) { throw new IOException("Not connected yet."); } if (uri==null) { uri=this.webdavResource.getPath(); } if (!uri.startsWith("/")) { uri = getPath() + uri; } return normalize(uri); } /** * Get the path. * * @return the path string. */ private String getPath() { return this.path; } /** * Return a context-relative path, beginning with a "/", that represents * the canonical version of the specified path after ".." and "." elements * are resolved out. If the specified path attempts to go outside the * boundaries of the current context (i.e. too many ".." path elements * are present), return <code>null</code> instead. * * @param path the path to be normalized. * @return the normalized path. */ private String normalize(String path) { if (path == null) { return null; } String normalized = path; // Normalize the slashes and add leading slash if necessary if (normalized.indexOf('\\') >= 0) { normalized = normalized.replace('\\', '/'); } if (!normalized.startsWith("/")) { normalized = "/" + normalized; } // Resolve occurrences of "/./" in the normalized path while (true) { int index = normalized.indexOf("/./"); if (index < 0) { break; } normalized = normalized.substring(0, index) + normalized.substring(index + 2); } // Resolve occurrences of "/../" in the normalized path while (true) { int index = normalized.indexOf("/../"); if (index < 0) { break; } if (index == 0) { return ("/"); // The only left path is the root. } int index2 = normalized.lastIndexOf('/', index - 1); normalized = normalized.substring(0, index2) + normalized.substring(index + 3); } // Resolve occurrences of "//" in the normalized path while (true) { int index = normalized.indexOf("//"); if (index < 0) { break; } normalized = normalized.substring(0, index) + normalized.substring(index + 1); } // Return the normalized path that we have completed return (normalized); } private void setPath(String path){ if (!path.endsWith("/")) { path = path + "/"; } this.path = normalize(path); } }