1.1 --- a/java/alt2xml-in-fs/src/cz/frantovo/alt2xml/in/fs/Reader.java Wed Oct 29 01:25:06 2014 +0100
1.2 +++ b/java/alt2xml-in-fs/src/cz/frantovo/alt2xml/in/fs/Reader.java Wed Oct 29 02:03:14 2014 +0100
1.3 @@ -22,6 +22,16 @@
1.4 import java.io.IOException;
1.5 import java.net.URI;
1.6 import java.net.URISyntaxException;
1.7 +import java.nio.ByteBuffer;
1.8 +import java.nio.file.Files;
1.9 +import java.nio.file.LinkOption;
1.10 +import java.nio.file.Path;
1.11 +import java.nio.file.attribute.PosixFilePermission;
1.12 +import java.nio.file.attribute.UserDefinedFileAttributeView;
1.13 +import java.nio.file.spi.FileSystemProvider;
1.14 +import java.util.List;
1.15 +import java.util.ArrayList;
1.16 +import java.util.Set;
1.17 import java.util.logging.Logger;
1.18 import org.xml.sax.Attributes;
1.19 import org.xml.sax.InputSource;
1.20 @@ -38,10 +48,21 @@
1.21 public static final String ROOT_ELEMENT = "fs";
1.22 public static final String DIR_ELEMENT = "dir";
1.23 public static final String FILE_ELEMENT = "file";
1.24 - public static final String ROOT_ATTRIBUTE = "root";
1.25 + public static final String XATTR_ELEMENT = "xattr";
1.26 + public static final String PERMISSIONS_ELEMENT = "mode";
1.27 + public static final String PERMISSIONS_U_ELEMENT = "user";
1.28 + public static final String PERMISSIONS_G_ELEMENT = "group";
1.29 + public static final String PERMISSIONS_O_ELEMENT = "others";
1.30 public static final String NAME_ATTRIBUTE = "name";
1.31 + public static final String ABSOLUTE_PATH_ATTRIBUTE = "path";
1.32 + public static final String SIZE_ATTRIBUTE = "size";
1.33 private static final Logger log = Logger.getLogger(Reader.class.getName());
1.34
1.35 + /**
1.36 + * indentation level
1.37 + */
1.38 + private int level = 0;
1.39 +
1.40 @Override
1.41 public void parse(InputSource input) throws IOException, SAXException {
1.42 File dir = getFile(input.getSystemId());
1.43 @@ -59,16 +80,38 @@
1.44 }
1.45 }
1.46
1.47 + private String getAbsolutePath(File file) throws IOException {
1.48 + return file.getCanonicalFile().getAbsolutePath();
1.49 + }
1.50 +
1.51 + private Attributes singleAttribute(String name, int value) {
1.52 + AttributesImpl attributes = new AttributesImpl();
1.53 + addAttribute(attributes, name, value);
1.54 + return attributes;
1.55 + }
1.56 +
1.57 private Attributes singleAttribute(String name, String value) {
1.58 AttributesImpl attributes = new AttributesImpl();
1.59 - attributes.addAttribute(null, name, name, "xs:string", value);
1.60 + addAttribute(attributes, name, value);
1.61 return attributes;
1.62 }
1.63
1.64 - private void outputStart(File root) throws SAXException {
1.65 + private void addAttribute(AttributesImpl attributes, String name, int value) {
1.66 + attributes.addAttribute(null, name, name, "xs:int", String.valueOf(value));
1.67 + }
1.68 +
1.69 + private void addAttribute(AttributesImpl attributes, String name, long value) {
1.70 + attributes.addAttribute(null, name, name, "xs:long", String.valueOf(value));
1.71 + }
1.72 +
1.73 + private void addAttribute(AttributesImpl attributes, String name, String value) {
1.74 + attributes.addAttribute(null, name, name, "xs:string", value);
1.75 + }
1.76 +
1.77 + private void outputStart(File root) throws SAXException, IOException {
1.78 contentHandler.startDocument();
1.79 contentHandler.lineBreak();
1.80 - contentHandler.startElement(null, null, ROOT_ELEMENT, singleAttribute(ROOT_ATTRIBUTE, root.getAbsolutePath()));
1.81 + contentHandler.startElement(null, null, ROOT_ELEMENT, singleAttribute(ABSOLUTE_PATH_ATTRIBUTE, getAbsolutePath(root)));
1.82 contentHandler.lineBreak();
1.83 }
1.84
1.85 @@ -78,22 +121,46 @@
1.86 contentHandler.endDocument();
1.87 }
1.88
1.89 - private void outputFile(File file) throws SAXException {
1.90 - contentHandler.startElement(null, null, FILE_ELEMENT, singleAttribute(NAME_ATTRIBUTE, file.getName()));
1.91 + private void outputFile(File file) throws SAXException, IOException {
1.92 + level++;
1.93 +
1.94 + AttributesImpl attributes = new AttributesImpl();
1.95 + addAttribute(attributes, NAME_ATTRIBUTE, file.getName());
1.96 + addAttribute(attributes, ABSOLUTE_PATH_ATTRIBUTE, getAbsolutePath(file));
1.97 + addAttribute(attributes, SIZE_ATTRIBUTE, file.length());
1.98 +
1.99 + contentHandler.indentation(level);
1.100 + contentHandler.startElement(null, null, FILE_ELEMENT, attributes);
1.101 contentHandler.lineBreak();
1.102
1.103 - //contentHandler.characters(file.getName());
1.104 + outputPermissions(file.toPath());
1.105 + outputExtendedAttributes(file);
1.106
1.107 + contentHandler.indentation(level);
1.108 contentHandler.endElement(null, null, FILE_ELEMENT);
1.109 contentHandler.lineBreak();
1.110 +
1.111 + level--;
1.112 }
1.113
1.114 - private void outputDir(File dir) throws SAXException {
1.115 + private void outputDir(File dir) throws SAXException, IOException {
1.116 + level++;
1.117
1.118 - contentHandler.startElement(null, null, DIR_ELEMENT, singleAttribute(NAME_ATTRIBUTE, dir.getName()));
1.119 + final File[] children = dir.listFiles();
1.120 +
1.121 + AttributesImpl attributes = new AttributesImpl();
1.122 + addAttribute(attributes, NAME_ATTRIBUTE, dir.getName());
1.123 + addAttribute(attributes, ABSOLUTE_PATH_ATTRIBUTE, getAbsolutePath(dir));
1.124 + addAttribute(attributes, SIZE_ATTRIBUTE, children.length);
1.125 +
1.126 + contentHandler.indentation(level);
1.127 + contentHandler.startElement(null, null, DIR_ELEMENT, attributes);
1.128 contentHandler.lineBreak();
1.129
1.130 - for (File file : dir.listFiles()) {
1.131 + outputPermissions(dir.toPath());
1.132 + outputExtendedAttributes(dir);
1.133 +
1.134 + for (File file : children) {
1.135 if (file.isDirectory()) {
1.136 outputDir(file);
1.137 } else {
1.138 @@ -101,7 +168,112 @@
1.139 }
1.140 }
1.141
1.142 + contentHandler.indentation(level);
1.143 contentHandler.endElement(null, null, DIR_ELEMENT);
1.144 contentHandler.lineBreak();
1.145 +
1.146 + level--;
1.147 + }
1.148 +
1.149 + private String encodeElementName(String originalName) {
1.150 + /**
1.151 + * TODO: encode and/or skip invalid characters
1.152 + */
1.153 + return originalName;
1.154 + }
1.155 +
1.156 + private void outputPermissions(Path path) throws IOException, SAXException {
1.157 + level++;
1.158 + Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(path, LinkOption.NOFOLLOW_LINKS);
1.159 +
1.160 + contentHandler.indentation(level);
1.161 + contentHandler.startElement(null, PERMISSIONS_ELEMENT, PERMISSIONS_ELEMENT, singleAttribute("octal", getOctal(permissions)));
1.162 + contentHandler.lineBreak();
1.163 +
1.164 + level++;
1.165 +
1.166 + outputPermission("owner", permissions.contains(PosixFilePermission.OWNER_READ), permissions.contains(PosixFilePermission.OWNER_WRITE), permissions.contains(PosixFilePermission.OWNER_EXECUTE));
1.167 + outputPermission("group", permissions.contains(PosixFilePermission.GROUP_READ), permissions.contains(PosixFilePermission.GROUP_WRITE), permissions.contains(PosixFilePermission.GROUP_EXECUTE));
1.168 + outputPermission("others", permissions.contains(PosixFilePermission.OTHERS_READ), permissions.contains(PosixFilePermission.OTHERS_WRITE), permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
1.169 +
1.170 + level--;
1.171 +
1.172 + contentHandler.indentation(level);
1.173 + contentHandler.endElement(null, PERMISSIONS_ELEMENT, PERMISSIONS_ELEMENT);
1.174 + contentHandler.lineBreak();
1.175 +
1.176 + level--;
1.177 + }
1.178 +
1.179 + private int getOctal(Set<PosixFilePermission> permissions) {
1.180 + int octal = 0;
1.181 +
1.182 + octal = octal + 100 * (permissions.contains(PosixFilePermission.OWNER_READ) ? 4 : 0);
1.183 + octal = octal + 100 * (permissions.contains(PosixFilePermission.OWNER_WRITE) ? 2 : 0);
1.184 + octal = octal + 100 * (permissions.contains(PosixFilePermission.OWNER_EXECUTE) ? 1 : 0);
1.185 +
1.186 + octal = octal + 10 * (permissions.contains(PosixFilePermission.GROUP_READ) ? 4 : 0);
1.187 + octal = octal + 10 * (permissions.contains(PosixFilePermission.GROUP_WRITE) ? 2 : 0);
1.188 + octal = octal + 10 * (permissions.contains(PosixFilePermission.GROUP_EXECUTE) ? 1 : 0);
1.189 +
1.190 + octal = octal + 1 * (permissions.contains(PosixFilePermission.OTHERS_READ) ? 4 : 0);
1.191 + octal = octal + 1 * (permissions.contains(PosixFilePermission.OTHERS_WRITE) ? 2 : 0);
1.192 + octal = octal + 1 * (permissions.contains(PosixFilePermission.OTHERS_EXECUTE) ? 1 : 0);
1.193 +
1.194 + return octal;
1.195 + }
1.196 +
1.197 + private void outputPermission(String name, boolean read, boolean write, boolean execute) throws SAXException {
1.198 + contentHandler.indentation(level);
1.199 + AttributesImpl attributes = new AttributesImpl();
1.200 + attributes.addAttribute(null, "read", "read", "xs:boolean", String.valueOf(read));
1.201 + attributes.addAttribute(null, "write", "write", "xs:boolean", String.valueOf(write));
1.202 + attributes.addAttribute(null, "execute", "execute", "xs:boolean", String.valueOf(execute));
1.203 + contentHandler.startElement(null, name, name, attributes);
1.204 + contentHandler.endElement(null, name, name);
1.205 + contentHandler.lineBreak();
1.206 + }
1.207 +
1.208 + private void outputExtendedAttributes(File file) throws IOException, SAXException {
1.209 + level++;
1.210 +
1.211 + final List<ExtendedAttribute> extendedAttributes = getExtendedAttributes(file);
1.212 +
1.213 + if (!extendedAttributes.isEmpty()) {
1.214 + contentHandler.indentation(level);
1.215 + contentHandler.startElement(null, XATTR_ELEMENT, XATTR_ELEMENT, null);
1.216 + contentHandler.lineBreak();
1.217 + level++;
1.218 + for (ExtendedAttribute ea : extendedAttributes) {
1.219 + contentHandler.indentation(level);
1.220 + String elementName = encodeElementName(ea.getKey());
1.221 + contentHandler.textElement(ea.getValue(), null, elementName, elementName, null);
1.222 + contentHandler.lineBreak();
1.223 + }
1.224 + level--;
1.225 + contentHandler.indentation(level);
1.226 + contentHandler.endElement(null, XATTR_ELEMENT, XATTR_ELEMENT);
1.227 + contentHandler.lineBreak();
1.228 + }
1.229 +
1.230 + level--;
1.231 + }
1.232 +
1.233 + private List<ExtendedAttribute> getExtendedAttributes(File file) throws IOException {
1.234 +
1.235 + List<ExtendedAttribute> l = new ArrayList<>();
1.236 +
1.237 + Path path = file.toPath();
1.238 + FileSystemProvider provider = path.getFileSystem().provider();
1.239 + UserDefinedFileAttributeView attributes = provider.getFileAttributeView(path, UserDefinedFileAttributeView.class);
1.240 +
1.241 + for (String jménoAtributu : attributes.list()) {
1.242 + ByteBuffer hodnotaAtributu = ByteBuffer.allocate(attributes.size(jménoAtributu));
1.243 + attributes.read(jménoAtributu, hodnotaAtributu);
1.244 + l.add(new ExtendedAttribute(jménoAtributu, hodnotaAtributu));
1.245 + }
1.246 +
1.247 + return l;
1.248 +
1.249 }
1.250 }