package org.nutz.resource.impl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.nutz.lang.Lang;
import org.nutz.lang.util.Disks;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.resource.NutResource;
import org.nutz.resource.Scans;
public abstract class ResourceLocation {
public abstract void scan(String base, Pattern pattern, List<NutResource> list);
public static ResourceLocation file(File root) {
try {
if (!root.exists())
return new ErrorResourceLocation(root);
return new FileSystemResourceLocation(root.getAbsoluteFile().getCanonicalFile());
} catch (Exception e) {
return new ErrorResourceLocation(root);
}
}
public static ResourceLocation jar(String jarPath) {
try {
return new JarResourceLocation(jarPath);
} catch (Exception e) {
return new ErrorResourceLocation(jarPath);
}
}
}
class FileSystemResourceLocation extends ResourceLocation {
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FileSystemResourceLocation other = (FileSystemResourceLocation) obj;
if (root == null) {
if (other.root != null)
return false;
} else if (!root.equals(other.root))
return false;
return true;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((root == null) ? 0 : root.hashCode());
return result;
}
public void scan(final String base, final Pattern pattern, final List<NutResource> list) {
final File baseFile = new File(root.getAbsolutePath()+"/"+base);
if (baseFile.isFile()) {
list.add(new FileResource(baseFile));
return;
}
Disks.visitFile(baseFile, new Scans.ResourceFileVisitor(list, base), new Scans.ResourceFileFilter(pattern));
}
public String toString() {
return "FileSystemResourceLocation [root=" + root + "]";
}
File root;
public FileSystemResourceLocation(File root) {
this.root = root;
}
}
class JarResourceLocation extends ResourceLocation {
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
JarResourceLocation other = (JarResourceLocation) obj;
if (jarPath == null) {
if (other.jarPath != null)
return false;
} else if (!jarPath.equals(other.jarPath))
return false;
return true;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((jarPath == null) ? 0 : jarPath.hashCode());
return result;
}
public void scan(String base, Pattern regex, List<NutResource> list) {
for (String ensName : names) {
String name = ensName;
if (name.contains("/"))
name = name.substring(name.lastIndexOf('/') + 1);
if (ensName.startsWith(base) && (null == regex || regex.matcher(name).find())) {
try {
list.add(Scans.makeJarNutResource(jarPath, ensName, base));
} catch (IOException e) {
if (log.isInfoEnabled())
log.info("Jar delete while scan?!! " + jarPath,e);
}
}
}
}
public String toString() {
return "JarResourceLocation [jarPath=" + jarPath + "]";
}
private static final Log log = Logs.get();
private List<String> names = new ArrayList<String>();
String jarPath;
public JarResourceLocation(String jarPath) {
this.jarPath = jarPath;
try {
ZipInputStream zis = Scans.makeZipInputStream(jarPath);
ZipEntry ens = null;
while (null != (ens = zis.getNextEntry())) {
if (ens.isDirectory())
continue;
names.add(ens.getName());
}
zis.close();
}
catch (Exception e) {
throw Lang.wrapThrow(e);
}
}
}