java/alt2xml-in-fs/src/cz/frantovo/alt2xml/in/fs/Reader.java
changeset 106 02739f60b1ec
parent 103 5e22fa13e016
child 109 76df01fc4aa2
     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  }