Skip to content

Commit

Permalink
made processors for @generated and @author.
Browse files Browse the repository at this point in the history
see phax#80.
  • Loading branch information
glelouet committed Jan 22, 2020
1 parent 390c40a commit 9b4b040
Show file tree
Hide file tree
Showing 7 changed files with 444 additions and 51 deletions.
116 changes: 80 additions & 36 deletions src/main/java/com/helger/jcodemodel/JCodeModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@
import java.io.IOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -64,6 +66,7 @@
import com.helger.jcodemodel.meta.CodeModelBuildingException;
import com.helger.jcodemodel.meta.ErrorTypeFound;
import com.helger.jcodemodel.meta.JCodeModelJavaxLangModelAdapter;
import com.helger.jcodemodel.preprocess.AJCodePreprocessor;
import com.helger.jcodemodel.util.EFileSystemConvention;
import com.helger.jcodemodel.util.FSName;
import com.helger.jcodemodel.util.IFileSystemConvention;
Expand Down Expand Up @@ -154,8 +157,9 @@ public static boolean isFileSystemCaseSensitive ()
m1.put (Void.class, Void.TYPE);

// Swap keys and values
for (final Map.Entry <Class <?>, Class <?>> e : m1.entrySet ())
for (final Map.Entry <Class <?>, Class <?>> e : m1.entrySet ()) {
m2.put (e.getValue (), e.getKey ());
}

s_aBoxToPrimitive = Collections.unmodifiableMap (m1);
s_aPrimitiveToBox = Collections.unmodifiableMap (m2);
Expand Down Expand Up @@ -234,8 +238,9 @@ public final IFileSystemConvention getFileSystemConvention ()
public final JCodeModel setFileSystemConvention (@Nonnull final IFileSystemConvention aFSConvention) throws JCodeModelException
{
JCValueEnforcer.notNull (aFSConvention, "FSConvention");
if (!m_aPackages.isEmpty () || !m_aResourceDirs.isEmpty ())
if (!m_aPackages.isEmpty () || !m_aResourceDirs.isEmpty ()) {
throw new JCodeModelException ("The FileSystem convention cannot be changed if a package or a resource directory already exists.");
}
m_aFSConvention = aFSConvention;
return this;
}
Expand Down Expand Up @@ -298,8 +303,9 @@ private static String _unifyPath (@Nonnull final String sName)
@Nonnull
private FSName _createFSName (@Nonnull final String sName)
{
if (m_aFSConvention.isCaseSensistive ())
if (m_aFSConvention.isCaseSensistive ()) {
return FSName.createCaseSensitive (sName);
}
return FSName.createCaseInsensitive (sName);
}

Expand All @@ -325,8 +331,9 @@ public JResourceDir resourceDir (@Nonnull final String sName) throws JCodeModelE
final String sCleanPath = _unifyPath (sName);

// 2. consistency checks
if (sCleanPath.startsWith (JResourceDir.SEPARATOR_STR))
if (sCleanPath.startsWith (JResourceDir.SEPARATOR_STR)) {
throw new IllegalArgumentException ("A resource directory may not be an absolute path: '" + sName + "'");
}

// 3. ensure root is present
final JResourceDir aRootDir = m_aResourceDirs.computeIfAbsent (_createFSName (""), k -> JResourceDir.root (this));
Expand All @@ -337,18 +344,20 @@ public JResourceDir resourceDir (@Nonnull final String sName) throws JCodeModelE
JResourceDir aCur = aRootDir;
for (final String sPart : JCStringHelper.getExplodedArray (JResourceDir.SEPARATOR, sCleanPath))
{
if (sDirName.length () > 0)
if (sDirName.length () > 0) {
sDirName += JResourceDir.SEPARATOR;
}
sDirName += sPart;

// Check if directory has a file with the name
if (aParentDir.hasResourceFile (sPart))
if (aParentDir.hasResourceFile (sPart)) {
throw new JResourceAlreadyExistsException (aParentDir.fullChildName (sPart));
}

// Get main subdir
final JResourceDir aFinalParentDir = aParentDir;
aCur = m_aResourceDirs.computeIfAbsent (_createFSName (sDirName),
k -> new JResourceDir (this, aFinalParentDir, k.getName ()));
k -> new JResourceDir (this, aFinalParentDir, k.getName ()));
aParentDir = aCur;
}

Expand All @@ -375,8 +384,9 @@ public JResourceDir rootResourceDir ()

public boolean containsResourceDir (@Nullable final String sAbsolutePath)
{
if (sAbsolutePath == null)
if (sAbsolutePath == null) {
return false;
}
// 1. unify name
final String sCleanPath = _unifyPath (sAbsolutePath);
// 2. check existence
Expand Down Expand Up @@ -419,16 +429,17 @@ public List <JResourceDir> getAllResourceDirs ()
*/
@Nonnull
public JDefinedClass _class (final int nMods,
@Nonnull final String sFullyQualifiedClassName,
@Nonnull final EClassType eClassType) throws JCodeModelException
@Nonnull final String sFullyQualifiedClassName,
@Nonnull final EClassType eClassType) throws JCodeModelException
{
final int nIdx = sFullyQualifiedClassName.lastIndexOf (JPackage.SEPARATOR);
if (nIdx < 0)
if (nIdx < 0) {
return rootPackage ()._class (nMods, sFullyQualifiedClassName, eClassType);
}
return _package (sFullyQualifiedClassName.substring (0, nIdx))._class (nMods,
sFullyQualifiedClassName.substring (nIdx +
1),
eClassType);
sFullyQualifiedClassName.substring (nIdx +
1),
eClassType);
}

/**
Expand Down Expand Up @@ -459,7 +470,7 @@ public JDefinedClass _class (@Nonnull final String sFullyQualifiedClassName) thr
*/
@Nonnull
public JDefinedClass _class (final int nMods,
@Nonnull final String sFullyQualifiedClassName) throws JCodeModelException
@Nonnull final String sFullyQualifiedClassName) throws JCodeModelException
{
return _class (nMods, sFullyQualifiedClassName, EClassType.CLASS);
}
Expand All @@ -477,7 +488,7 @@ public JDefinedClass _class (final int nMods,
*/
@Nonnull
public JDefinedClass _class (@Nonnull final String sFullyQualifiedClassName,
@Nonnull final EClassType eClassType) throws JCodeModelException
@Nonnull final EClassType eClassType) throws JCodeModelException
{
return _class (JMod.PUBLIC, sFullyQualifiedClassName, eClassType);
}
Expand Down Expand Up @@ -597,9 +608,11 @@ public JErrorClass errorClass (@Nonnull final String sMessage, @Nullable final S
public boolean buildsErrorTypeRefs ()
{
// avoid concurrent modification exception
for (final JPackage aPackage : getAllPackages ())
if (aPackage.buildsErrorTypeRefs ())
for (final JPackage aPackage : getAllPackages ()) {
if (aPackage.buildsErrorTypeRefs ()) {
return true;
}
}
return false;
}

Expand All @@ -615,10 +628,11 @@ public boolean buildsErrorTypeRefs ()
public JDefinedClass _getClass (@Nonnull final String sFullyQualifiedClassName)
{
final int nIndex = sFullyQualifiedClassName.lastIndexOf (JPackage.SEPARATOR);
if (nIndex < 0)
if (nIndex < 0) {
return rootPackage ()._getClass (sFullyQualifiedClassName);
}
return _package (sFullyQualifiedClassName.substring (0,
nIndex))._getClass (sFullyQualifiedClassName.substring (nIndex + 1));
nIndex))._getClass (sFullyQualifiedClassName.substring (nIndex + 1));
}

/**
Expand Down Expand Up @@ -752,8 +766,8 @@ public void build (@Nonnull final File aDestDir, @Nullable final PrintStream aSt
@Deprecated
@ChangeInV4
public void build (@Nonnull final File aSrcDir,
@Nonnull final File aResourceDir,
@Nullable final PrintStream aStatusPS) throws IOException
@Nonnull final File aResourceDir,
@Nullable final PrintStream aStatusPS) throws IOException
{
AbstractCodeWriter res = new FileCodeWriter (aResourceDir, m_aBuildingCharset, m_sBuildingNewLine);
AbstractCodeWriter src = new FileCodeWriter (aSrcDir, m_aBuildingCharset, m_sBuildingNewLine);
Expand Down Expand Up @@ -833,7 +847,7 @@ public void build (@Nonnull final AbstractCodeWriter aWriter) throws IOException
@Deprecated
@ChangeInV4
public void build (@Nonnull final AbstractCodeWriter aSource,
@Nonnull final AbstractCodeWriter aResource) throws IOException
@Nonnull final AbstractCodeWriter aResource) throws IOException
{
new JCMWriter (this).setCharset (m_aBuildingCharset).setNewLine (m_sBuildingNewLine).build (aSource, aResource);
}
Expand All @@ -847,10 +861,12 @@ public int countArtifacts ()
{
int r = 0;
// avoid concurrent modification exception
for (final JPackage aItem : new ArrayList <> (m_aPackages.values ()))
for (final JPackage aItem : new ArrayList <> (m_aPackages.values ())) {
r += aItem.countArtifacts ();
for (final JResourceDir aItem : new ArrayList <> (m_aResourceDirs.values ()))
}
for (final JResourceDir aItem : new ArrayList <> (m_aResourceDirs.values ())) {
r += aItem.countArtifacts ();
}
return r;
}

Expand Down Expand Up @@ -921,7 +937,7 @@ public AbstractJClass ref (@Nonnull final Class <?> aClazz)
*/
@Nonnull
public JDefinedClass ref (@Nonnull final TypeElement aElement,
@Nonnull final Elements aElementUtils) throws ErrorTypeFound, CodeModelBuildingException
@Nonnull final Elements aElementUtils) throws ErrorTypeFound, CodeModelBuildingException
{
final JCodeModelJavaxLangModelAdapter adapter = new JCodeModelJavaxLangModelAdapter (this, aElementUtils);
return adapter.getClass (aElement);
Expand Down Expand Up @@ -958,7 +974,7 @@ public JDefinedClass ref (@Nonnull final TypeElement aElement,
*/
@Nonnull
public JDefinedClass refWithErrorTypes (@Nonnull final TypeElement aElement,
@Nonnull final Elements aElementUtils) throws CodeModelBuildingException
@Nonnull final Elements aElementUtils) throws CodeModelBuildingException
{
final JCodeModelJavaxLangModelAdapter adapter = new JCodeModelJavaxLangModelAdapter (this, aElementUtils);
return adapter.getClassWithErrorTypes (aElement);
Expand All @@ -976,8 +992,9 @@ public JDefinedClass refWithErrorTypes (@Nonnull final TypeElement aElement,
@Nonnull
public AbstractJType _ref (@Nonnull final Class <?> aClass)
{
if (aClass.isPrimitive ())
if (aClass.isPrimitive ()) {
return AbstractJType.parse (this, aClass.getName ());
}
return ref (aClass);
}

Expand Down Expand Up @@ -1118,16 +1135,17 @@ AbstractJClass parseTypeName ()

// not supported
throw new IllegalArgumentException ("only extends/super can follow ?, but found " +
m_sTypeName.substring (m_nIdx));
m_sTypeName.substring (m_nIdx));
}

while (m_nIdx < m_sTypeName.length ())
{
final char ch = m_sTypeName.charAt (m_nIdx);
if (Character.isJavaIdentifierStart (ch) || Character.isJavaIdentifierPart (ch) || ch == '.')
if (Character.isJavaIdentifierStart (ch) || Character.isJavaIdentifierPart (ch) || ch == '.') {
m_nIdx++;
else
} else {
break;
}
}

final AbstractJClass aClazz = ref (m_sTypeName.substring (nStart, m_nIdx));
Expand All @@ -1149,8 +1167,9 @@ private AbstractJClass _parseSuffix (@Nonnull final AbstractJClass aClazz)

final char ch = m_sTypeName.charAt (m_nIdx);

if (ch == '<')
if (ch == '<') {
return _parseSuffix (_parseArguments (aClazz));
}

if (ch == '[')
{
Expand All @@ -1170,8 +1189,9 @@ private AbstractJClass _parseSuffix (@Nonnull final AbstractJClass aClazz)
*/
private void _skipWs ()
{
while (Character.isWhitespace (m_sTypeName.charAt (m_nIdx)) && m_nIdx < m_sTypeName.length ())
while (Character.isWhitespace (m_sTypeName.charAt (m_nIdx)) && m_nIdx < m_sTypeName.length ()) {
m_nIdx++;
}
}

/**
Expand All @@ -1190,14 +1210,17 @@ private AbstractJClass _parseArguments (@Nonnull final AbstractJClass aRawType)
while (true)
{
args.add (parseTypeName ());
if (m_nIdx == m_sTypeName.length ())
if (m_nIdx == m_sTypeName.length ()) {
throw new IllegalArgumentException ("Missing '>' in " + m_sTypeName);
}
final char ch = m_sTypeName.charAt (m_nIdx);
if (ch == '>')
if (ch == '>') {
return aRawType.narrow (args);
}

if (ch != ',')
if (ch != ',') {
throw new IllegalArgumentException (m_sTypeName);
}
m_nIdx++;
}
}
Expand Down Expand Up @@ -1242,4 +1265,25 @@ public Set <AbstractJClass> getAllDontImportClasses ()
{
return new HashSet <> (m_aDontImportClasses);
}

private final HashMap<Class<? extends AJCodePreprocessor>, AJCodePreprocessor> m_preprocessors = new HashMap<>();

public <T extends AJCodePreprocessor> T processor(Class<T> processorClass) {
@SuppressWarnings("unchecked")
T ret = (T) m_preprocessors.get(processorClass);
if (ret == null) {
try {
ret = processorClass.getConstructor().newInstance();
m_preprocessors.put(processorClass, ret);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
throw new UnsupportedOperationException("catch this", e);
}
}
return ret;
}

public Collection<AJCodePreprocessor> getProcessors() {
return Collections.unmodifiableCollection(m_preprocessors.values());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.helger.jcodemodel.preprocess;

import com.helger.jcodemodel.JCodeModel;

/**
* A preprocessor adds data in a JCodeModel before it is built.<br />
* <p>
* This is typically usefull for, but not limited to:
* </p>
*
*
* <p>
* the typical use case is
* <ol>
* <li>During JCM modeling, the user requests the preprocessor with
* JCM::preprocessor(preprocessorclass). This preprocessor instance is unique in
* the JCM for that preprocessor class.</li>
* <li>the preprocessor is used during the JCM modeling, eg by tagging classes,
* fields, packages, etc with it eg myprocessor.add(myJCMClass)</li>
* <li>when the user wants to build the JCM, the JCM calls each preprocessor
* that has been requested, which can then modify the JCM</li>
* <li>if several processors are requested and at least one modified the JCM
* when applied, each processor is applied again, until none generates a
* modification anymore</li>
* </ol>
* </p>
*
* <p>
* A preprocessor class must be have an unparametrized constructor. The settings
* are set after initialization.
* </p>
*
* @author glelouet
*
*/
public abstract class AJCodePreprocessor {

/**
*
* @param jcm the {@link JCodeModel} we want to apply the processor onto.
* @param firstPass
* true when the processor has not bee applied to the jcm already.
* Typically that means them odifications the processor wanted to do
* have already been applied, by itself.
* @return true if the application of the processor modified the jcm.
*/
public abstract boolean apply(JCodeModel jcm, boolean firstPass);

}
Loading

0 comments on commit 9b4b040

Please sign in to comment.