Skip to content

Commit

Permalink
[JXR-170] NullPointerException while parsing Java 15 multi-line Strin…
Browse files Browse the repository at this point in the history
…g source

- Add support for parsing sources with Java 15 multi-line Strings
- Add JUnit test case
- Implement toString on class BaseType
- Require non-null name on BaseType construtor
- Prevent construction of types with null name
- Add version to maven-enforcer-plugin plugin to prevent failure of integration test JXR-143_nofork
  • Loading branch information
spannm authored and slawekjaranowski committed Jul 25, 2022
1 parent a803fbf commit 87995c6
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 28 deletions.
1 change: 1 addition & 0 deletions maven-jxr-plugin/src/it/JXR-143_nofork/pom.xml
Expand Up @@ -44,6 +44,7 @@ under the License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<goals>
Expand Down
29 changes: 16 additions & 13 deletions maven-jxr/src/main/java/org/apache/maven/jxr/pacman/BaseType.java
Expand Up @@ -19,15 +19,26 @@
* under the License.
*/

import java.util.Objects;

/**
* put your documentation comment here
*
* @author jvanzyl
*/
public abstract class BaseType
{
private String name = null;
private final String name;

/**
* Construct type and set its name.
*
* @param name type name
*/
public BaseType( String name )
{
this.name = Objects.requireNonNull( name );
}

/**
* Get the name for this type
Expand All @@ -36,22 +47,14 @@ public abstract class BaseType
*/
public String getName()
{
if ( name == null )
{
return "";
}
return this.name;
}


/**
* Set the name for this type
*
* @param name The new name value
*/
public void setName( String name )
@Override
public String toString()
{
this.name = name;
return getClass().getSimpleName() + "[name=" + name + "]";
}

}

Expand Up @@ -41,7 +41,7 @@ public class ClassType
@Deprecated
public ClassType( String name )
{
this.setName( name );
this( name, null );
}

/**
Expand All @@ -52,7 +52,8 @@ public ClassType( String name )
*/
public ClassType( String name, String filename )
{
this.setName( name );
super( name );

this.setFilename( filename );
}

Expand Down
Expand Up @@ -39,7 +39,7 @@ public class ImportType
*/
public ImportType( String name )
{
this.setName( name );
super( name );

//compute member variables

Expand Down
Expand Up @@ -84,6 +84,9 @@ private void parseRecursive( String nestedPrefix, StreamTokenizer stok )
{
int openBracesCount = 0;

char prevttype = Character.MIN_VALUE; // previous token type
boolean inTripleQuote = false; // used to toggle between inside/outside triple-quoted multi-line strings

while ( stok.nextToken() != StreamTokenizer.TT_EOF )
{

Expand All @@ -103,12 +106,28 @@ else if ( stok.ttype == '}' )
}
continue;
}
else
{
if ( '"' == stok.ttype && '"' == prevttype )
{
inTripleQuote = !inTripleQuote;
}
prevttype = (char) stok.ttype;
if ( inTripleQuote )
{
// skip content found inside triple-quoted multi-line Java 15 String
continue;
}
}

//set the package
if ( "package".equals( stok.sval ) && stok.ttype != '\"' )
{
stok.nextToken();
this.setPackageType( new PackageType( stok.sval ) );
if ( stok.sval != null )
{
this.setPackageType( new PackageType( stok.sval ) );
}
}

//set the imports
Expand All @@ -125,23 +144,28 @@ and packages that are imported with this (ex "test.*") will be
stripped( and become "test." ). Here we need to test for this
and if necessary re-add the char.
*/
if ( name.charAt( name.length() - 1 ) == '.' )
if ( name != null )
{
name = name + '*';
if ( name.charAt( name.length() - 1 ) == '.' )
{
name = name + '*';
}
this.addImportType( new ImportType( name ) );
}

this.addImportType( new ImportType( name ) );
}

// Add the class or classes. There can be several classes in one file so
// continue with the while loop to get them all.
if ( ( "class".equals( stok.sval ) || "interface".equals( stok.sval ) || "enum".equals( stok.sval ) )
&& stok.ttype != '\"' )
&& stok.ttype != '"' )
{
stok.nextToken();
this.addClassType( new ClassType( nestedPrefix + stok.sval,
getFilenameWithoutPathOrExtension( this.getPath() ) ) );
parseRecursive( nestedPrefix + stok.sval + ".", stok );
if ( stok.sval != null )
{
this.addClassType( new ClassType( nestedPrefix + stok.sval,
getFilenameWithoutPathOrExtension( this.getPath() ) ) );
parseRecursive( nestedPrefix + stok.sval + ".", stok );
}
}

}
Expand Down
Expand Up @@ -39,17 +39,17 @@ public class PackageType
*/
public PackageType( String name )
{
this.setName( name );
super( name );
}

/**
* Create a Java package with no name IE the default Java package.
*/
public PackageType()
{
super( "" );
}


/**
* Get all the known classes
*/
Expand Down
Expand Up @@ -46,4 +46,14 @@ public void testJXR_135_lotsOfNested() throws IOException
assertEquals( "NotNested", classTypes.next().getName() );
}

}
@Test
public void testJXR_170_multiLineString() throws IOException
{
JavaFileImpl javaFile = new JavaFileImpl( Paths.get(
"src/test/resources/jxr170/org/apache/maven/jxr/pacman/ClassWithMultiLineString.java" ),
"UTF-8" );
assertEquals( 1, javaFile.getClassTypes().size() );
assertEquals( "ClassWithMultiLineString", javaFile.getClassTypes().get(0).getName() );
assertEquals( "[ImportType[name=java.lang.*]]", javaFile.getImportTypes().toString() );
}
}
@@ -0,0 +1,40 @@
package org.apache.maven.jxr;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
* Test Java source of the test for JXR-170.
*
* @author Markus Spann
*/
public class ClassWithMultiLineString {

private final String str;

public ClassWithMultiLineString(String _str) {
str = _str;
}

public static void main(String[] args) {
new ClassWithMultiLineString("""
import java.util.List;
""");
}
}

0 comments on commit 87995c6

Please sign in to comment.