001 /* 002 * Copyright (C) 2003-2009 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020 package org.crsh.jcr; 021 022 import org.slf4j.Logger; 023 import org.slf4j.LoggerFactory; 024 025 import java.io.IOException; 026 027 /** 028 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 029 * @version $Revision$ 030 */ 031 abstract class FileSystemAction { 032 033 /** . */ 034 private static final Logger log = LoggerFactory.getLogger(FileSystemAction.class); 035 036 public static void read(SCPCommand cmd, FileSystem fs) throws IOException { 037 cmd.ack(); 038 log.debug("Want to read line"); 039 String line = cmd.readLine(); 040 log.debug("Read line " + line); 041 FileSystemAction action = decode(line); 042 log.debug("Action: " + action); 043 read(cmd, action, fs); 044 } 045 046 private static void read(final SCPCommand cmd, FileSystemAction action, FileSystem fs) throws IOException { 047 if (action instanceof StartDirectory) { 048 String directoryName = ((StartDirectory)action).name; 049 fs.startDirectory(directoryName); 050 051 // 052 cmd.ack(); 053 054 // 055 while (true) { 056 String nextLine = cmd.readLine(); 057 FileSystemAction nextAction = decode(nextLine); 058 log.debug("Next action: " + nextAction); 059 if (nextAction instanceof FileSystemAction.EndDirectory) { 060 fs.endDirectory(directoryName); 061 break; 062 } else { 063 read(cmd, nextAction, fs); 064 } 065 } 066 067 // 068 cmd.ack(); 069 } else if (action instanceof File) { 070 File file = (File)action; 071 072 // 073 cmd.ack(); 074 075 // 076 fs.file(file.name, file.length, cmd.read(file.length)); 077 078 // 079 log.debug("About to send ack for file"); 080 cmd.ack(); 081 cmd.readAck(); 082 } 083 } 084 085 private static FileSystemAction decode(String line) { 086 if (line == null) { 087 throw new NullPointerException(); 088 } 089 if (line.length() == 0) { 090 throw new IllegalArgumentException("Line has length zero"); 091 } 092 char t = line.charAt(0); 093 if (t == 'C' || t == 'D') { 094 095 // 096 int length; 097 int endLength = line.indexOf(' ', 6); 098 if (endLength == -1) { 099 throw new IllegalArgumentException(); 100 } else { 101 String s = line.substring(6, endLength); 102 if (s.length() == 1 && s.charAt(0) == '0') { 103 // Optimize for directories 104 length = 0; 105 } else { 106 try { 107 length = Integer.parseInt(s); 108 } 109 catch (NumberFormatException e) { 110 throw new IllegalArgumentException("Could not parse file length " + s); 111 } 112 } 113 } 114 115 // 116 String name = line.substring(endLength + 1); 117 118 // 119 if (t == 'D') { 120 return new StartDirectory(name); 121 } else { 122 return new File(name, length); 123 } 124 } else if (t == 'E') { 125 return new EndDirectory(); 126 } else { 127 throw new IllegalArgumentException("Could not recognize file system action " + line); 128 } 129 } 130 131 private static class StartDirectory extends FileSystemAction { 132 133 /** . */ 134 private final String name; 135 136 private StartDirectory(String name) { 137 this.name = name; 138 } 139 140 @Override 141 public String toString() { 142 return "StartDirectory[name=" + name + "]"; 143 } 144 } 145 146 private static class File extends FileSystemAction { 147 148 /** . */ 149 private final String name; 150 151 /** . */ 152 private final int length; 153 154 private File(String name, int length) { 155 this.name = name; 156 this.length = length; 157 } 158 159 @Override 160 public String toString() { 161 return "File[name=" + name + ",length=" + length + "]"; 162 } 163 } 164 165 private static class EndDirectory extends FileSystemAction { 166 private EndDirectory() { 167 } 168 169 @Override 170 public String toString() { 171 return "EndDirectory[]"; 172 } 173 } 174 }