001 /* 002 * Copyright (C) 2012 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 java.io.IOException; 023 import java.util.logging.Level; 024 import java.util.logging.Logger; 025 026 abstract class FileSystemAction { 027 028 /** . */ 029 private static final Logger log = Logger.getLogger(FileSystemAction.class.getName()); 030 031 public static void read(SCPCommand cmd, FileSystem fs) throws IOException { 032 cmd.ack(); 033 log.log(Level.FINE, "Want to read line"); 034 String line = cmd.readLine(); 035 log.log(Level.FINE, "Read line " + line); 036 FileSystemAction action = decode(line); 037 log.log(Level.FINE, "Action: " + action); 038 read(cmd, action, fs); 039 } 040 041 private static void read(final SCPCommand cmd, FileSystemAction action, FileSystem fs) throws IOException { 042 if (action instanceof StartDirectory) { 043 String directoryName = ((StartDirectory)action).name; 044 fs.beginDirectory(directoryName); 045 046 // 047 cmd.ack(); 048 049 // 050 while (true) { 051 String nextLine = cmd.readLine(); 052 FileSystemAction nextAction = decode(nextLine); 053 log.log(Level.FINE, "Next action: " + nextAction); 054 if (nextAction instanceof FileSystemAction.EndDirectory) { 055 fs.endDirectory(directoryName); 056 break; 057 } else { 058 read(cmd, nextAction, fs); 059 } 060 } 061 062 // 063 cmd.ack(); 064 } else if (action instanceof File) { 065 File file = (File)action; 066 067 // 068 cmd.ack(); 069 070 // 071 fs.file(file.name, file.length, cmd.read(file.length)); 072 073 // 074 log.log(Level.FINE, "About to send ack for file"); 075 cmd.ack(); 076 cmd.readAck(); 077 } 078 } 079 080 private static FileSystemAction decode(String line) { 081 if (line == null) { 082 throw new NullPointerException(); 083 } 084 if (line.length() == 0) { 085 throw new IllegalArgumentException("Line has length zero"); 086 } 087 char t = line.charAt(0); 088 if (t == 'C' || t == 'D') { 089 090 // 091 int length; 092 int endLength = line.indexOf(' ', 6); 093 if (endLength == -1) { 094 throw new IllegalArgumentException(); 095 } else { 096 String s = line.substring(6, endLength); 097 if (s.length() == 1 && s.charAt(0) == '0') { 098 // Optimize for directories 099 length = 0; 100 } else { 101 try { 102 length = Integer.parseInt(s); 103 } 104 catch (NumberFormatException e) { 105 throw new IllegalArgumentException("Could not parse file length " + s); 106 } 107 } 108 } 109 110 // 111 String name = line.substring(endLength + 1); 112 113 // 114 if (t == 'D') { 115 return new StartDirectory(name); 116 } else { 117 return new File(name, length); 118 } 119 } else if (t == 'E') { 120 return new EndDirectory(); 121 } else { 122 throw new IllegalArgumentException("Could not recognize file system action " + line); 123 } 124 } 125 126 private static class StartDirectory extends FileSystemAction { 127 128 /** . */ 129 private final String name; 130 131 private StartDirectory(String name) { 132 this.name = name; 133 } 134 135 @Override 136 public String toString() { 137 return "StartDirectory[name=" + name + "]"; 138 } 139 } 140 141 private static class File extends FileSystemAction { 142 143 /** . */ 144 private final String name; 145 146 /** . */ 147 private final int length; 148 149 private File(String name, int length) { 150 this.name = name; 151 this.length = length; 152 } 153 154 @Override 155 public String toString() { 156 return "File[name=" + name + ",length=" + length + "]"; 157 } 158 } 159 160 private static class EndDirectory extends FileSystemAction { 161 private EndDirectory() { 162 } 163 164 @Override 165 public String toString() { 166 return "EndDirectory[]"; 167 } 168 } 169 }