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 }