001/*license*\ 002 Codelet: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com) 003 004 This software is dual-licensed under the: 005 - Lesser General Public License (LGPL) version 3.0 or, at your option, any later version; 006 - Apache Software License (ASL) version 2.0. 007 008 Either license may be applied at your discretion. More information may be found at 009 - http://en.wikipedia.org/wiki/Multi-licensing. 010 011 The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at: 012 - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 013 - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 014\*license*/ 015package com.github.aliteralmind.codelet.util; 016 import com.github.xbn.util.JavaUtil; 017 import com.github.xbn.io.PathMustBe; 018 import com.github.xbn.io.Existence; 019 import com.github.xbn.io.NewPrintWriterToFile; 020 import com.github.xbn.io.PlainTextFileUtil; 021 import com.github.xbn.io.Readable; 022 import com.github.xbn.io.Writable; 023 import com.github.xbn.lang.Copyable; 024 import com.github.xbn.lang.CrashIfObject; 025 import java.io.PrintWriter; 026 import java.nio.file.AccessDeniedException; 027 import java.nio.file.NoSuchFileException; 028 import java.nio.file.Path; 029 import java.nio.file.Paths; 030 import java.util.Iterator; 031/** 032 <p>Given a base directory and fully-qualified class name, get a {@link java.nio.file.Path}, {@link org.apache.commons.io.LineIterator}, or {@link java.io.PrintWriter} to its source code, class file, or JavaDoc html file. The fully-qualified class name may or may not represent an actually-existing class (as determined by {@code Class.forName(s)}).</p> 033 034 * @since 0.1.0 035 * @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://codelet.aliteralmind.com">{@code http://codelet.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/codelet">{@code https://github.com/aliteralmind/codelet}</a> 036 **/ 037public class FQClassNameWithBaseDir implements Copyable { 038 private final String baseDir ; 039 private final String fqClsNm ; 040 private final Path javaPath ; 041 private final String dotPlusXtn; 042 public FQClassNameWithBaseDir(String base_dir, String fq_className, String dot_plusExtension) { 043 try { 044 if(!dot_plusExtension.startsWith(".")) { 045 throw new IllegalArgumentException("dot_plusExtension (" + dot_plusExtension + ") does not start with a dot."); 046 } 047 } catch(RuntimeException rx) { 048 throw CrashIfObject.nullOrReturnCause(dot_plusExtension, "dot_plusExtension", null, rx); 049 } 050 String path = JavaUtil.getPathForJavaClass(base_dir, fq_className, dot_plusExtension); 051 052 //Set parameters into fields here, so toString() can be used in error messages. 053 baseDir = base_dir; 054 fqClsNm = fq_className; 055 dotPlusXtn = dot_plusExtension; 056 javaPath = Paths.get(path); 057 } 058 /** 059 <p>Create a new instance as a duplicate of another.</p> 060 061 * @param to_copy May not be <code>null</code>. 062 * @see #getObjectCopy() 063 */ 064 public FQClassNameWithBaseDir(FQClassNameWithBaseDir to_copy) { 065 this(to_copy, null, null, null); 066 } 067 /** 068 <p>Create a new instance as a duplicate of another.</p> 069 070 * @param to_copy May not be <code>null</code>. 071 * @see #getObjectCopy() 072 */ 073 public FQClassNameWithBaseDir(FQClassNameWithBaseDir to_copy, String baseDir_override, String fqClsName_override, String dotXtnsn_override) { 074 this(((baseDir_override == null) ? (new ToCopyHandler(to_copy)).getBaseDirectory() : baseDir_override), 075 ((fqClsName_override == null) ? (new ToCopyHandler(to_copy)).getClassName() : fqClsName_override), 076 ((dotXtnsn_override == null) ? (new ToCopyHandler(to_copy)).getDotPlusExtension() : dotXtnsn_override)); 077 } 078 public FQClassNameWithBaseDir getThisOrCrashIfBad(Readable readable_is, Writable writable_is) throws NoSuchFileException, AccessDeniedException { 079 getThisOrCrashIfBad(Existence.REQUIRED, readable_is, writable_is); 080 return this; 081 } 082 public FQClassNameWithBaseDir getThisOrCrashIfBad(Existence existence_is, Readable readable_is, Writable writable_is) throws NoSuchFileException, AccessDeniedException { 083 new PathMustBe(). 084 existing(existence_is).readable(readable_is).writable(writable_is). 085 crashIfBad(getPath(), "getPath()"); 086 return this; 087 } 088 089 public Iterator<String> newLineIterator() { 090 try { 091 return PlainTextFileUtil.getLineIterator(getPath().toFile(), "getPath().toFile()"); 092 } catch(RuntimeException rx) { 093 throw new RuntimeException("Attempting PlainTextFileUtil.getLineIterator(getPath().toFile(), ...), this=[" + this + "]", rx); 094 } 095 } 096 public String getFileText() { 097 try { 098 return PlainTextFileUtil.getText(getPath().toFile(), "getPath().toFile()"); 099 } catch(RuntimeException rx) { 100 throw new RuntimeException("Attempting PlainTextFileUtil.getText(getPath().toFile(), ...), this=[" + this + "]", rx); 101 } 102 } 103 public StringBuilder appendText(StringBuilder to_appendTo) { 104 try { 105 return PlainTextFileUtil.appendText(to_appendTo, getPath().toFile(), "getPath().toFile()"); 106 } catch(RuntimeException rx) { 107 throw new RuntimeException("Attempting PlainTextFileUtil.appendText(to_appendTo, getPath().toFile(), ...), this=[" + this + "]", rx); 108 } 109 } 110 public PrintWriter newFileWriter() { 111 return new NewPrintWriterToFile().overwrite().autoFlush(). 112 build(getPath().toString()); 113 } 114 public String getBaseDirectory() { 115 return baseDir; 116 } 117 public String getClassName() { 118 return fqClsNm; 119 } 120 public Path getPath() { 121 return javaPath; 122 } 123 public String getDotPlusExtension() { 124 return dotPlusXtn; 125 } 126 public String toString() { 127 return "base=" + getBaseDirectory() + ", class=" + getClassName() + ", dot-extension=" + getDotPlusExtension() + ", absolute=" + getPath().toAbsolutePath(); 128 } 129 /** 130 <p>Get a duplicate of this <code>FQClassNameWithBaseDir</code>.</p> 131 132 * @return <code>(new {@link #FQClassNameWithBaseDir(FQClassNameWithBaseDir) FQClassNameWithBaseDir}(this))</code> 133 */ 134 public FQClassNameWithBaseDir getObjectCopy() { 135 return (new FQClassNameWithBaseDir(this)); 136 } 137 public static final Iterator<String> newLineIteratorForExistingReadable(String base_dir, String fq_className, String dot_plusExtension) throws NoSuchFileException, AccessDeniedException { 138 return new FQClassNameWithBaseDir( 139 base_dir, fq_className, dot_plusExtension). 140 getThisOrCrashIfBad(Existence.REQUIRED, Readable.REQUIRED, Writable.OPTIONAL). 141 newLineIterator(); 142 } 143 public static final PrintWriter newFileWriterForWriteable(String base_dir, String fq_className, String dot_plusExtension) throws NoSuchFileException, AccessDeniedException { 144 return new FQClassNameWithBaseDir( 145 base_dir, fq_className, dot_plusExtension). 146 getThisOrCrashIfBad(Readable.OPTIONAL, Writable.REQUIRED). 147 newFileWriter(); 148 } 149} 150class ToCopyHandler { 151 private final FQClassNameWithBaseDir toCopy; 152 ToCopyHandler(FQClassNameWithBaseDir to_copy) { 153 toCopy = to_copy; 154 } 155 public String getBaseDirectory() { 156 try { 157 return toCopy.getBaseDirectory(); 158 } catch(RuntimeException rx) { 159 throw CrashIfObject.nullOrReturnCause(toCopy, "to_copy", null, rx); 160 } 161 } 162 public String getClassName() { 163 try { 164 return toCopy.getClassName(); 165 } catch(RuntimeException rx) { 166 throw CrashIfObject.nullOrReturnCause(toCopy, "to_copy", null, rx); 167 } 168 } 169 public String getDotPlusExtension() { 170 try { 171 return toCopy.getDotPlusExtension(); 172 } catch(RuntimeException rx) { 173 throw CrashIfObject.nullOrReturnCause(toCopy, "to_copy", null, rx); 174 } 175 } 176}