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}