mirror of https://github.com/gnosygnu/xowa
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
11 KiB
245 lines
11 KiB
/*
|
|
XOWA: the XOWA Offline Wiki Application
|
|
Copyright (C) 2012 gnosygnu@gmail.com
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package gplx.ios; import gplx.*;
|
|
public interface IoUrlInfo {
|
|
String Key();
|
|
byte DirSpr_byte();
|
|
String DirSpr();
|
|
boolean CaseSensitive();
|
|
String EngineKey();
|
|
|
|
boolean Match(String raw);
|
|
boolean IsDir(String raw);
|
|
String Xto_api(String raw);
|
|
String OwnerDir(String raw);
|
|
String OwnerRoot(String raw);
|
|
String NameAndExt(String raw);
|
|
String NameOnly(String raw);
|
|
String Ext(String raw);
|
|
String XtoRootName(String raw, int rawLen);
|
|
}
|
|
class IoUrlInfo_nil implements IoUrlInfo {
|
|
public String Key() {return KeyConst;} public static final String KeyConst = String_.Null_mark;
|
|
public String EngineKey() {return "<<INVALID>>";}
|
|
public String DirSpr() {return "<<INVALID>>";}
|
|
public byte DirSpr_byte() {return Byte_ascii.Slash;}
|
|
public String VolSpr() {return "<<INVALID>>";}
|
|
public boolean CaseSensitive() {return false;}
|
|
public boolean Match(String raw) {return false;}
|
|
public boolean IsDir(String raw) {return false;}
|
|
public String Xto_api(String raw) {return "";}
|
|
public String OwnerDir(String raw) {return IoUrlInfo_base.NullString;}
|
|
public String OwnerRoot(String raw) {return IoUrlInfo_base.NullString;}
|
|
public String NameAndExt(String raw) {return "";}
|
|
public String NameOnly(String raw) {return "";}
|
|
public String Ext(String raw) {return "";}
|
|
public String XtoRootName(String raw, int rawLen) {return "";}
|
|
public static final IoUrlInfo_nil Instance = new IoUrlInfo_nil(); IoUrlInfo_nil() {}
|
|
}
|
|
abstract class IoUrlInfo_base implements IoUrlInfo {
|
|
@gplx.Internal protected static final int DirSprLen = 1;
|
|
@gplx.Internal protected static final String NullString = "", ExtSeparator = ".";
|
|
public abstract String Key();
|
|
public abstract byte DirSpr_byte();
|
|
public abstract String DirSpr();
|
|
public abstract boolean CaseSensitive();
|
|
public abstract boolean Match(String raw);
|
|
public abstract String EngineKey();
|
|
public boolean IsDir(String raw) {return String_.Has_at_end(raw, DirSpr());}
|
|
public abstract String XtoRootName(String raw, int rawLen);
|
|
@gplx.Virtual public String Xto_api(String raw) {
|
|
return IsDir(raw)
|
|
? String_.DelEnd(raw, IoUrlInfo_base.DirSprLen) // if Dir, remove trailing DirSpr, since most api will not expect it (ex: .Delete will malfunction)
|
|
: raw;
|
|
}
|
|
public String OwnerDir(String raw) {
|
|
int rawLen = String_.Len(raw);
|
|
int ownerDirSprPos = OwnerDirPos(raw, rawLen);
|
|
if (ownerDirSprPos <= OwnerDirPos_hasNoOwner) return IoUrlInfo_base.NullString; // no ownerDir found; return Null; only (a) NullUrls (b) RootUrls ("C:\") (c) relative ("fil.txt")
|
|
return String_.MidByLen(raw, 0, ownerDirSprPos + 1); // +1 to include backslash
|
|
}
|
|
@gplx.Virtual public String OwnerRoot(String raw) {
|
|
String temp = raw, rv = raw;
|
|
while (true) {
|
|
temp = OwnerDir(temp);
|
|
if (String_.Eq(temp, IoUrlInfo_base.NullString)) break;
|
|
rv = temp;
|
|
}
|
|
return rv;
|
|
}
|
|
public String NameAndExt(String raw) { // if Dir, will return \ as last char
|
|
int rawLen = String_.Len(raw);
|
|
int ownerDirSprPos = OwnerDirPos(raw, rawLen);
|
|
if (ownerDirSprPos == OwnerDirPos_isNull) return IoUrlInfo_base.NullString; // NullUrl and RootUrl return Null;
|
|
return ownerDirSprPos == OwnerDirPos_hasNoOwner || ownerDirSprPos == OwnerDirPos_isRoot
|
|
? raw // no PathSeparator b/c (a) RootDir ("C:\"); (b) relative ("fil.txt")
|
|
: String_.DelBgn(raw, ownerDirSprPos + 1); // +1 to skip backslash
|
|
}
|
|
public String NameOnly(String raw) {
|
|
String nameAndExt = NameAndExt(raw);
|
|
if (IsDir(raw)) {
|
|
String rootName = XtoRootName(raw, String_.Len(raw)); // C:\ -> C; / -> root
|
|
return rootName == null
|
|
? String_.DelEnd(nameAndExt, IoUrlInfo_base.DirSprLen)
|
|
: rootName;
|
|
}
|
|
int pos = String_.FindBwd(nameAndExt, IoUrlInfo_base.ExtSeparator);
|
|
return pos == String_.Find_none
|
|
? nameAndExt // Ext not found; return entire NameAndExt
|
|
: String_.MidByLen(nameAndExt, 0, pos);
|
|
}
|
|
public String Ext(String raw) { // if Dir, return DirSpr; if Fil, return . as first char; ex: .txt; .png
|
|
if (IsDir(raw)) return this.DirSpr();
|
|
String nameAndExt = NameAndExt(raw);
|
|
int pos = String_.FindBwd(nameAndExt, IoUrlInfo_base.ExtSeparator);
|
|
return pos == String_.Find_none ? "" : String_.DelBgn(nameAndExt, pos);
|
|
}
|
|
int OwnerDirPos(String raw, int rawLen) {
|
|
if (rawLen == 0) return OwnerDirPos_isNull;
|
|
else if (XtoRootName(raw, rawLen) != null) return OwnerDirPos_isRoot;
|
|
else {// NullUrls and RootUrls have no owners
|
|
int posAdj = IsDir(raw) ? IoUrlInfo_base.DirSprLen : 0; // Dir ends with DirSpr, adjust lastIndex by DirSprLen
|
|
return String_.FindBwd(raw, this.DirSpr(), rawLen - 1 - posAdj); // -1 to adjust for LastIdx
|
|
}
|
|
}
|
|
static final int
|
|
OwnerDirPos_hasNoOwner = -1 // List_adp_.NotFound
|
|
, OwnerDirPos_isNull = -2
|
|
, OwnerDirPos_isRoot = -3;
|
|
}
|
|
class IoUrlInfo_wnt extends IoUrlInfo_base {
|
|
@Override public String Key() {return "wnt";}
|
|
@Override public String EngineKey() {return IoEngine_.SysKey;}
|
|
@Override public String DirSpr() {return Op_sys.Wnt.Fsys_dir_spr_str();}
|
|
@Override public byte DirSpr_byte() {return Byte_ascii.Backslash;}
|
|
@Override public boolean CaseSensitive() {return Op_sys.Wnt.Fsys_case_match();}
|
|
@Override public boolean Match(String raw) {return String_.Len(raw) > 1 && String_.CharAt(raw, 1) == ':';} // 2nd char is :; assumes 1 letter drives
|
|
@Override public String XtoRootName(String raw, int rawLen) {
|
|
return rawLen == 3 && String_.CharAt(raw, 1) == ':' // only allow single letter drives; ex: C:\; note, CharAt(raw, 1) to match Match
|
|
? Char_.To_str(String_.CharAt(raw, 0))
|
|
: null;
|
|
}
|
|
public static final IoUrlInfo_wnt Instance = new IoUrlInfo_wnt(); IoUrlInfo_wnt() {}
|
|
}
|
|
class IoUrlInfo_lnx extends IoUrlInfo_base {
|
|
@Override public String Key() {return "lnx";}
|
|
@Override public String EngineKey() {return IoEngine_.SysKey;}
|
|
@Override public String DirSpr() {return DirSprStr;} static final String DirSprStr = Op_sys.Lnx.Fsys_dir_spr_str();
|
|
@Override public byte DirSpr_byte() {return Byte_ascii.Slash;}
|
|
@Override public boolean CaseSensitive() {return Op_sys.Lnx.Fsys_case_match();}
|
|
@Override public boolean Match(String raw) {return String_.Has_at_bgn(raw, DirSprStr);} // anything that starts with /
|
|
@Override public String XtoRootName(String raw, int rawLen) {
|
|
return rawLen == 1 && String_.Eq(raw, DirSprStr)
|
|
? "root"
|
|
: null;
|
|
}
|
|
@Override public String OwnerRoot(String raw) {return DirSprStr;} // drive is always /
|
|
@Override public String Xto_api(String raw) {
|
|
return String_.Eq(raw, DirSprStr) // is root
|
|
? DirSprStr
|
|
: super.Xto_api(raw); // NOTE: super.Xto_api will strip off last /
|
|
}
|
|
public static final IoUrlInfo_lnx Instance = new IoUrlInfo_lnx(); IoUrlInfo_lnx() {}
|
|
}
|
|
class IoUrlInfo_rel extends IoUrlInfo_base {
|
|
@Override public String Key() {return "rel";}
|
|
@Override public String EngineKey() {return IoEngine_.SysKey;}
|
|
@Override public String DirSpr() {return info.DirSpr();}
|
|
@Override public byte DirSpr_byte() {return info.DirSpr_byte();}
|
|
@Override public boolean CaseSensitive() {return info.CaseSensitive();}
|
|
@Override public String XtoRootName(String raw, int rawLen) {return info.XtoRootName(raw, rawLen);}
|
|
@Override public boolean Match(String raw) {return true;} // relPath is always lastResort; return true
|
|
IoUrlInfo info;
|
|
public static IoUrlInfo_rel new_(IoUrlInfo info) {
|
|
IoUrlInfo_rel rv = new IoUrlInfo_rel();
|
|
rv.info = info;
|
|
return rv;
|
|
} IoUrlInfo_rel() {}
|
|
}
|
|
class IoUrlInfo_mem extends IoUrlInfo_base {
|
|
@Override public String Key() {return key;} private String key;
|
|
@Override public String EngineKey() {return engineKey;} private String engineKey;
|
|
@Override public String DirSpr() {return "/";}
|
|
@Override public byte DirSpr_byte() {return Byte_ascii.Slash;}
|
|
@Override public boolean CaseSensitive() {return false;}
|
|
@Override public String XtoRootName(String raw, int rawLen) {
|
|
return String_.Eq(raw, key) ? String_.DelEnd(key, 1) : null;
|
|
}
|
|
@Override public boolean Match(String raw) {return String_.Has_at_bgn(raw, key);}
|
|
public static IoUrlInfo_mem new_(String key, String engineKey) {
|
|
IoUrlInfo_mem rv = new IoUrlInfo_mem();
|
|
rv.key = key; rv.engineKey = engineKey;
|
|
return rv;
|
|
} IoUrlInfo_mem() {}
|
|
}
|
|
class IoUrlInfo_alias extends IoUrlInfo_base {
|
|
@Override public String Key() {return srcDir;}
|
|
@Override public String EngineKey() {return engineKey;} private String engineKey;
|
|
@Override public String DirSpr() {return srcDirSpr;}
|
|
@Override public byte DirSpr_byte() {return srcDirSpr_byte;} private byte srcDirSpr_byte;
|
|
@Override public boolean CaseSensitive() {return false;}
|
|
@Override public String XtoRootName(String raw, int rawLen) {
|
|
return String_.Eq(raw, srcRootDir) ? srcRootName : null;
|
|
}
|
|
@Override public boolean Match(String raw) {return String_.Has_at_bgn(raw, srcDir);}
|
|
@Override public String Xto_api(String raw) {
|
|
String rv = String_.Replace(raw, srcDir, trgDir); // replace src with trg
|
|
if (!String_.Eq(srcDirSpr, trgDirSpr)) rv = String_.Replace(rv, srcDirSpr, trgDirSpr); // replace dirSprs
|
|
return IsDir(raw)
|
|
? String_.DelEnd(rv, IoUrlInfo_base.DirSprLen) // remove trailingSeparator, else Directory.Delete will not work properly
|
|
: rv;
|
|
}
|
|
void SrcDir_set(String v) {
|
|
srcDir = v;
|
|
boolean lnx = DirSpr_lnx(v);
|
|
if (srcDirSpr == null) {
|
|
if (lnx) {
|
|
srcDirSpr = Op_sys.Lnx.Fsys_dir_spr_str();
|
|
srcDirSpr_byte = Op_sys.Lnx.Fsys_dir_spr_byte();
|
|
}
|
|
else {
|
|
srcDirSpr = Op_sys.Wnt.Fsys_dir_spr_str();
|
|
srcDirSpr_byte = Op_sys.Wnt.Fsys_dir_spr_byte();
|
|
}
|
|
}
|
|
if (srcRootName == null) srcRootName = lnx ? "root" : String_.Mid(srcDir, 0, String_.FindFwd(srcDir, ":"));
|
|
if (srcRootDir == null) srcRootDir = lnx ? "/" : srcDir;
|
|
}
|
|
void TrgDir_set(String v) {
|
|
trgDir = v;
|
|
boolean lnx = DirSpr_lnx(v);
|
|
if (trgDirSpr == null) trgDirSpr = lnx ? Op_sys.Lnx.Fsys_dir_spr_str() : Op_sys.Wnt.Fsys_dir_spr_str();
|
|
}
|
|
boolean DirSpr_lnx(String s) {return String_.Has(s, Op_sys.Lnx.Fsys_dir_spr_str());}
|
|
void EngineKey_set(String v) {engineKey = v;}
|
|
String srcDir, trgDir, srcDirSpr, trgDirSpr, srcRootDir, srcRootName;
|
|
public static IoUrlInfo_alias new_(String srcDir, String trgDir, String engineKey) {
|
|
IoUrlInfo_alias rv = new IoUrlInfo_alias();
|
|
rv.SrcDir_set(srcDir);
|
|
rv.TrgDir_set(trgDir);
|
|
rv.EngineKey_set(engineKey);
|
|
return rv;
|
|
}
|
|
public static final IoUrlInfo_alias KEYS = new IoUrlInfo_alias();
|
|
public final String
|
|
Data_EngineKey = "engineKey"
|
|
, Data_SrcDir = "srcDir"
|
|
, Data_TrgDir = "trgDir"
|
|
;
|
|
}
|