PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sys/java/fan/sys/Sys.java

https://bitbucket.org/bedlaczech/fan-1.0
Java | 627 lines | 448 code | 79 blank | 100 comment | 50 complexity | abe70e71b1f9d7995f50fd16e586f619 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //
  2. // Copyright (c) 2006, Brian Frank and Andy Frank
  3. // Licensed under the Academic Free License version 3.0
  4. //
  5. // History:
  6. // 2 Dec 05 Brian Frank Creation
  7. //
  8. package fan.sys;
  9. import java.lang.ref.*;
  10. import java.io.File;
  11. import java.util.Iterator;
  12. import java.lang.management.*;
  13. import fanx.fcode.*;
  14. import fanx.util.*;
  15. /**
  16. * Sys provides static access to the system's environment and initializes
  17. * key data structures in a specific order in its static initializer.
  18. */
  19. public final class Sys
  20. {
  21. //////////////////////////////////////////////////////////////////////////
  22. // Fields (loaded before type constants)
  23. //////////////////////////////////////////////////////////////////////////
  24. /** Env.os constant */
  25. public static final String os = initOs();
  26. /** Env.arch constant */
  27. public static final String arch = initArch();
  28. /** Env.platform constant */
  29. public static final String platform = os + "-" + arch;
  30. /** Booting from only a JAR distribution? */
  31. public static final boolean isJarDist = initIsJarDist();
  32. /** BootEnv.homeDir */
  33. public static final File homeDir = initHomeDir();
  34. /** {BootEnv.homeDir}/lib/fan/ */
  35. public static final File podsDir = initPodsDir();
  36. /** {BootEnv.homeDir}/lib/fan/sys.pod */
  37. public static final Pod sysPod = initSysPod();
  38. //////////////////////////////////////////////////////////////////////////
  39. // Java Version
  40. //////////////////////////////////////////////////////////////////////////
  41. public static int JAVA_1_5 = 15;
  42. public static int JAVA_1_6 = 16;
  43. public static int JAVA_1_7 = 17;
  44. /** Java version 1.5, 1.6, 1.7, etc */
  45. public static int javaVersion = initJavaVersion();
  46. //////////////////////////////////////////////////////////////////////////
  47. // Fields (type constants)
  48. //////////////////////////////////////////////////////////////////////////
  49. // the Eve of all types
  50. public static final Type ObjType = initType("Obj");
  51. // basic primitives
  52. public static final Type NumType = initType("Num");
  53. public static final Type EnumType = initType("Enum");
  54. public static final Type FacetType = initType("Facet");
  55. public static final Type BoolType = initType("Bool");
  56. public static final Type DurationType = initType("Duration");
  57. public static final Type FuncType = initType("Func");
  58. public static final Type IntType = initType("Int");
  59. public static final Type DecimalType = initType("Decimal");
  60. public static final Type FloatType = initType("Float");
  61. public static final Type ListType = initType("List");
  62. public static final Type MapType = initType("Map");
  63. public static final Type MonthType = initType("Month");
  64. public static final Type PodType = initType("Pod");
  65. public static final Type RangeType = initType("Range");
  66. public static final Type StrType = initType("Str");
  67. public static final Type StrBufType = initType("StrBuf");
  68. public static final Type TestType = initType("Test");
  69. public static final Type DateTimeType = initType("DateTime");
  70. public static final Type DateType = initType("Date");
  71. public static final Type TimeType = initType("Time");
  72. public static final Type TimeZoneType = initType("TimeZone");
  73. public static final Type TypeType = initType("Type");
  74. public static final Type WeekdayType = initType("Weekday");
  75. public static final Type ThisType = initType("This");
  76. public static final Type VoidType = initType("Void");
  77. public static final Type EnvType = initType("Env");
  78. public static final Type BootEnvType = initType("BootEnv");
  79. public static final Type JarDistEnvType = initType("JarDistEnv");
  80. // reflection
  81. public static final Type SlotType = initType("Slot");
  82. public static final Type FieldType = initType("Field");
  83. public static final Type MethodType = initType("Method");
  84. public static final Type ParamType = initType("Param");
  85. // IO
  86. public static final Type CharsetType = initType("Charset");
  87. public static final Type EndianType = initType("Endian");
  88. public static final Type InStreamType = initType("InStream");
  89. public static final Type SysInStreamType = initType("SysInStream");
  90. public static final Type OutStreamType = initType("OutStream");
  91. public static final Type SysOutStreamType = initType("SysOutStream");
  92. public static final Type FileType = initType("File");
  93. public static final Type LocalFileType = initType("LocalFile");
  94. public static final Type ZipEntryFileType = initType("ZipEntryFile");
  95. public static final Type BufType = initType("Buf");
  96. public static final Type MemBufType = initType("MemBuf");
  97. public static final Type FileBufType = initType("FileBuf");
  98. public static final Type NioBufType = initType("NioBuf");
  99. public static final Type UriType = initType("Uri");
  100. public static final Type ZipType = initType("Zip");
  101. public static final Type ClassLoaderFileType = initType("ClassLoaderFile");
  102. public static final Type FileStoreType = initType("FileStore");
  103. public static final Type LocalFileStoreType = initType("LocalFileStore");
  104. // utils
  105. public static final Type DependType = initType("Depend");
  106. public static final Type LogType = initType("Log");
  107. public static final Type LogLevelType = initType("LogLevel");
  108. public static final Type LogRecType = initType("LogRec");
  109. public static final Type LocaleType = initType("Locale");
  110. public static final Type MimeTypeType = initType("MimeType");
  111. public static final Type ProcessType = initType("Process");
  112. public static final Type RegexType = initType("Regex");
  113. public static final Type RegexMatcherType = initType("RegexMatcher");
  114. public static final Type ServiceType = initType("Service");
  115. public static final Type VersionType = initType("Version");
  116. public static final Type UnitType = initType("Unit");
  117. public static final Type UnsafeType = initType("Unsafe");
  118. public static final Type UuidType = initType("Uuid");
  119. // uri schemes
  120. public static final Type UriSchemeType = initType("UriScheme");
  121. public static final Type FanSchemeType = initType("FanScheme");
  122. public static final Type FileSchemeType = initType("FileScheme");
  123. // facets
  124. public static final Type TransientType = initType("Transient");
  125. public static final Type SerializableType = initType("Serializable");
  126. public static final Type JsType = initType("Js");
  127. public static final Type NoDocType = initType("NoDoc");
  128. public static final Type DeprecatedType = initType("Deprecated");
  129. public static final Type OperatorType = initType("Operator");
  130. public static final Type FacetMetaType = initType("FacetMeta");
  131. // exceptions
  132. public static final Type ErrType = initType("Err");
  133. public static final Type ArgErrType = initType("ArgErr");
  134. public static final Type CancelledErrType = initType("CancelledErr");
  135. public static final Type CastErrType = initType("CastErr");
  136. public static final Type ConstErrType = initType("ConstErr");
  137. public static final Type FieldNotSetErrType = initType("FieldNotSetErr");
  138. public static final Type IOErrType = initType("IOErr");
  139. public static final Type IndexErrType = initType("IndexErr");
  140. public static final Type InterruptedErrType = initType("InterruptedErr");
  141. public static final Type NameErrType = initType("NameErr");
  142. public static final Type NotImmutableErrType = initType("NotImmutableErr");
  143. public static final Type NullErrType = initType("NullErr");
  144. public static final Type ParseErrType = initType("ParseErr");
  145. public static final Type ReadonlyErrType = initType("ReadonlyErr");
  146. public static final Type TestErrType = initType("TestErr");
  147. public static final Type TimeoutErrType = initType("TimeoutErr");
  148. public static final Type UnknownKeyErrType = initType("UnknownKeyErr");
  149. public static final Type UnknownPodErrType = initType("UnknownPodErr");
  150. public static final Type UnknownServiceErrType = initType("UnknownServiceErr");
  151. public static final Type UnknownSlotErrType = initType("UnknownSlotErr");
  152. public static final Type UnknownFacetErrType = initType("UnknownFacetErr");
  153. public static final Type UnknownTypeErrType = initType("UnknownTypeErr");
  154. public static final Type UnresolvedErrType = initType("UnresolvedErr");
  155. public static final Type UnsupportedErrType = initType("UnsupportedErr");
  156. // generic parameter types used with generic types List, Map, and Method
  157. static final ClassType[] genericParamTypes = new ClassType[256];
  158. public static final ClassType AType = initGeneric('A');
  159. public static final ClassType BType = initGeneric('B');
  160. public static final ClassType CType = initGeneric('C');
  161. public static final ClassType DType = initGeneric('D');
  162. public static final ClassType EType = initGeneric('E');
  163. public static final ClassType FType = initGeneric('F');
  164. public static final ClassType GType = initGeneric('G');
  165. public static final ClassType HType = initGeneric('H');
  166. public static final ClassType KType = initGeneric('K');
  167. public static final ClassType LType = initGeneric('L');
  168. public static final ClassType MType = initGeneric('M');
  169. public static final ClassType RType = initGeneric('R');
  170. public static final ClassType VType = initGeneric('V');
  171. static { initGenericParamTypes(); }
  172. //////////////////////////////////////////////////////////////////////////
  173. // Fields (loaded after type constants)
  174. //////////////////////////////////////////////////////////////////////////
  175. /** Empty Str:Obj? map */
  176. public static final Map emptyStrObjMap = initEmptyStrMap(ObjType.toNullable());
  177. /** Empty Str:Str map */
  178. public static final Map emptyStrStrMap = initEmptyStrMap(StrType);
  179. /** Empty Str:Type map */
  180. public static final Map emptyStrTypeMap = initEmptyStrMap(TypeType);
  181. /** Bootstrap environment */
  182. public static final BootEnv bootEnv = new BootEnv();
  183. static Env curEnv = bootEnv;
  184. /** {BootEnv.homeDir}/etc/sys/config.props */
  185. public static final Map sysConfig = initSysConfig();
  186. /** Config prop used to generating debug attributes in bytecode */
  187. public static final boolean debug = sysConfigBool("debug", false);
  188. /** Config prop used to determine max stack trace */
  189. public static final int errTraceMaxDepth = sysConfigInt("errTraceMaxDepth", 25);
  190. /** Absolute boot time */
  191. public static final DateTime bootDateTime = initBootDateTime();
  192. /** Relative boot time */
  193. public static final Duration bootDuration = initBootDuration();
  194. /** Current environment - do this after sys fully booted */
  195. static
  196. {
  197. initEnv();
  198. initEnvClassPath();
  199. }
  200. //////////////////////////////////////////////////////////////////////////
  201. // Platform Init
  202. //////////////////////////////////////////////////////////////////////////
  203. private static String initOs()
  204. {
  205. try
  206. {
  207. String os = System.getProperty("os.name", "unknown");
  208. os = sanitize(os);
  209. if (os.contains("win")) return "win32";
  210. if (os.contains("mac")) return "macosx";
  211. if (os.contains("sunos")) return "solaris";
  212. return os;
  213. }
  214. catch (Throwable e)
  215. {
  216. throw initFail("os", e);
  217. }
  218. }
  219. private static String initArch()
  220. {
  221. try
  222. {
  223. String arch = System.getProperty("os.arch", "unknown");
  224. arch = sanitize(arch);
  225. if (arch.contains("i386")) return "x86";
  226. if (arch.contains("amd64")) return "x86_64";
  227. return arch;
  228. }
  229. catch (Throwable e)
  230. {
  231. throw initFail("arch", e);
  232. }
  233. }
  234. private static String sanitize(String s)
  235. {
  236. StringBuilder buf = new StringBuilder();
  237. for (int i=0; i<s.length(); ++i)
  238. {
  239. int c = s.charAt(i);
  240. if (c == '_') { buf.append((char)c); continue; }
  241. if ('a' <= c && c <= 'z') { buf.append((char)c); continue; }
  242. if ('0' <= c && c <= '9') { buf.append((char)c); continue; }
  243. if ('A' <= c && c <= 'Z') { buf.append((char)(c | 0x20)); continue; }
  244. // skip it
  245. }
  246. return buf.toString();
  247. }
  248. //////////////////////////////////////////////////////////////////////////
  249. // Init isJarDist
  250. //////////////////////////////////////////////////////////////////////////
  251. private static boolean initIsJarDist()
  252. {
  253. return System.getProperty("fan.jardist", "false").equals("true");
  254. }
  255. //////////////////////////////////////////////////////////////////////////
  256. // Dir Init
  257. //////////////////////////////////////////////////////////////////////////
  258. private static File initHomeDir()
  259. {
  260. try
  261. {
  262. return sysPropToDir("fan.home", "FAN_HOME", null);
  263. }
  264. catch (Throwable e)
  265. {
  266. throw initFail("homeDir", e);
  267. }
  268. }
  269. private static File initPodsDir()
  270. {
  271. try
  272. {
  273. return new File(homeDir, "lib" + File.separator + "fan");
  274. }
  275. catch (Throwable e)
  276. {
  277. throw initFail("podsDir", e);
  278. }
  279. }
  280. private static File sysPropToDir(String propKey, String envKey, String def)
  281. {
  282. // lookup system property
  283. String val = System.getProperty(propKey);
  284. // fallback to environment variable
  285. if (val == null)
  286. val = System.getenv(envKey);
  287. if (val == null)
  288. val = System.getenv(FanStr.lower(envKey));
  289. // fallback to def if provides
  290. if (val == null && def != null)
  291. val = def;
  292. // if still not found then we're toast
  293. if (val == null)
  294. throw new RuntimeException("Missing " + propKey + " system property or " + envKey + " env var");
  295. // check that val ends in trailing newline
  296. if (!val.endsWith("/")) val += "/";
  297. // map to java.io.File and check that it is a valid directory
  298. File f = new File(val);
  299. if (!f.exists() || !f.isDirectory())
  300. throw new RuntimeException("Invalid " + propKey + " dir: " + f);
  301. return f;
  302. }
  303. //////////////////////////////////////////////////////////////////////////
  304. // Init Sys Pod
  305. //////////////////////////////////////////////////////////////////////////
  306. static Pod initSysPod()
  307. {
  308. try
  309. {
  310. return Pod.doFind("sys", true, null, null);
  311. }
  312. catch (Throwable e)
  313. {
  314. throw initFail("sysPod", e);
  315. }
  316. }
  317. //////////////////////////////////////////////////////////////////////////
  318. // Init Java Version
  319. //////////////////////////////////////////////////////////////////////////
  320. static int initJavaVersion()
  321. {
  322. try
  323. {
  324. String s = System.getProperty("java.version", "1.5.0");
  325. if (s.startsWith("1.7.")) return JAVA_1_7;
  326. if (s.startsWith("1.6.")) return JAVA_1_6;
  327. return JAVA_1_5;
  328. }
  329. catch (Throwable e)
  330. {
  331. throw initFail("javaVersion", e);
  332. }
  333. }
  334. //////////////////////////////////////////////////////////////////////////
  335. // Init Types
  336. //////////////////////////////////////////////////////////////////////////
  337. static Type initType(String name)
  338. {
  339. try
  340. {
  341. return sysPod.type(name, true);
  342. }
  343. catch (Throwable e)
  344. {
  345. throw initFail("type " + name, e);
  346. }
  347. }
  348. private static ClassType initGeneric(int ch)
  349. {
  350. String name = String.valueOf((char)ch);
  351. try
  352. {
  353. return genericParamTypes[ch] = new ClassType(sysPod, name, 0, null);
  354. }
  355. catch (Throwable e)
  356. {
  357. throw initFail("generic " + name, e);
  358. }
  359. }
  360. private static void initGenericParamTypes()
  361. {
  362. List noMixins = new List(TypeType, 0).ro();
  363. for (int i=0; i<genericParamTypes.length; ++i)
  364. {
  365. ClassType gp = genericParamTypes[i];
  366. if (gp == null) continue;
  367. gp.base = ObjType;
  368. gp.mixins = noMixins;
  369. }
  370. }
  371. public static Type genericParamType(String name)
  372. {
  373. if (name.length() == 1 && name.charAt(0) < genericParamTypes.length)
  374. return genericParamTypes[name.charAt(0)];
  375. else
  376. return null;
  377. }
  378. //////////////////////////////////////////////////////////////////////////
  379. // Init Env
  380. //////////////////////////////////////////////////////////////////////////
  381. private static void initEnv()
  382. {
  383. try
  384. {
  385. // if running from JAR, we have to use special JarDistEnv
  386. if (isJarDist)
  387. {
  388. curEnv = JarDistEnv.make();
  389. return;
  390. }
  391. // check FAN_ENV environment variable
  392. String var = (String)Env.cur().vars().get("FAN_ENV");
  393. if (var != null)
  394. {
  395. curEnv = (Env)Type.find(var).make();
  396. return;
  397. }
  398. // lookup up from current directory to find "fan.props" file
  399. File dir = new File(".").getCanonicalFile();
  400. while (dir != null)
  401. {
  402. File fanFile = new File(dir, "fan.props");
  403. if (fanFile.exists())
  404. {
  405. curEnv = (Env)Type.find("util::PathEnv").method("makeProps").call(new LocalFile(fanFile));
  406. return;
  407. }
  408. dir = dir.getParentFile();
  409. }
  410. }
  411. catch (Exception e)
  412. {
  413. initWarn("curEnv", e);
  414. }
  415. }
  416. private static void initEnvClassPath()
  417. {
  418. try
  419. {
  420. // add environment's work dir to classpath
  421. LocalFile homeDir = (LocalFile)curEnv.homeDir();
  422. LocalFile workDir = (LocalFile)curEnv.workDir();
  423. if (!homeDir.equals(workDir))
  424. FanClassLoader.extClassLoader.addFanDir(workDir.file);
  425. }
  426. catch (Exception e)
  427. {
  428. initWarn("envClassPath", e);
  429. }
  430. }
  431. //////////////////////////////////////////////////////////////////////////
  432. // Empty Maps
  433. //////////////////////////////////////////////////////////////////////////
  434. private static Map initEmptyStrMap(Type v)
  435. {
  436. try
  437. {
  438. return (Map)new Map(StrType, v).toImmutable();
  439. }
  440. catch (Exception e)
  441. {
  442. throw initFail("emptyStrMap", e);
  443. }
  444. }
  445. //////////////////////////////////////////////////////////////////////////
  446. // Sys Config
  447. //////////////////////////////////////////////////////////////////////////
  448. private static Map initSysConfig()
  449. {
  450. try
  451. {
  452. String sep = java.io.File.separator;
  453. LocalFile f = new LocalFile(new java.io.File(homeDir, "etc" + sep + "sys" + sep + "config.props"));
  454. if (f.exists())
  455. {
  456. try
  457. {
  458. return f.readProps();
  459. }
  460. catch (Exception e)
  461. {
  462. System.out.println("ERROR: Invalid props file: " + f);
  463. System.out.println(" " + e);
  464. }
  465. }
  466. }
  467. catch (Throwable e)
  468. {
  469. throw initFail("sysConfig", e);
  470. }
  471. return emptyStrStrMap;
  472. }
  473. static String sysConfig(String name)
  474. {
  475. return (String)sysConfig.get(name);
  476. }
  477. static boolean sysConfigBool(String name, boolean def)
  478. {
  479. String val = sysConfig(name);
  480. if (val != null) return val.equals("true");
  481. return def;
  482. }
  483. static int sysConfigInt(String name, int def)
  484. {
  485. try
  486. {
  487. String val = sysConfig(name);
  488. if (val != null) return Integer.parseInt(val);
  489. }
  490. catch (Exception e) {}
  491. return def;
  492. }
  493. //////////////////////////////////////////////////////////////////////////
  494. // Boot Times
  495. //////////////////////////////////////////////////////////////////////////
  496. private static Duration initBootDuration()
  497. {
  498. try
  499. {
  500. return Duration.now();
  501. }
  502. catch (Throwable e)
  503. {
  504. throw initFail("bootDuration", e);
  505. }
  506. }
  507. private static DateTime initBootDateTime()
  508. {
  509. try
  510. {
  511. return DateTime.now();
  512. }
  513. catch (Throwable e)
  514. {
  515. throw initFail("bootDuration", e);
  516. }
  517. }
  518. //////////////////////////////////////////////////////////////////////////
  519. // Utils
  520. //////////////////////////////////////////////////////////////////////////
  521. private static void initWarn(String field, Throwable e)
  522. {
  523. System.out.println("WARN: cannot init Sys." + field);
  524. e.printStackTrace();
  525. }
  526. private static RuntimeException initFail(String field, Throwable e)
  527. {
  528. System.out.println("ERROR: cannot init Sys." + field);
  529. e.printStackTrace();
  530. throw new RuntimeException("Cannot boot fan: " + e.toString());
  531. }
  532. /**
  533. * Make a thread-safe copy of the specified object.
  534. * If it is immutable, then just return it; otherwise
  535. * we make a serialized copy.
  536. */
  537. public static Object safe(Object obj)
  538. {
  539. if (obj == null) return null;
  540. if (FanObj.isImmutable(obj)) return obj;
  541. Buf buf = new MemBuf(512);
  542. buf.out.writeObj(obj);
  543. buf.flip();
  544. return buf.in.readObj();
  545. }
  546. /** Force sys class to load */
  547. public static void boot() {}
  548. }