24 package org.lightjason.agentspeak;
26 import com.github.javaparser.JavaParser;
27 import com.github.javaparser.ParseProblemException;
28 import com.github.javaparser.ast.PackageDeclaration;
29 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
30 import com.github.javaparser.ast.body.EnumDeclaration;
31 import com.github.javaparser.ast.expr.MethodCallExpr;
32 import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
33 import org.apache.commons.lang3.ClassUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.junit.Test;
39 import java.io.FileInputStream;
40 import java.io.IOException;
42 import java.nio.file.FileSystems;
43 import java.nio.file.Files;
44 import java.nio.file.Paths;
45 import java.text.MessageFormat;
46 import java.util.Arrays;
47 import java.util.Collections;
48 import java.util.HashMap;
49 import java.util.HashSet;
50 import java.util.Locale;
52 import java.util.Properties;
54 import java.util.regex.Matcher;
55 import java.util.regex.Pattern;
56 import java.util.stream.Collectors;
57 import java.util.stream.IntStream;
58 import java.util.stream.Stream;
60 import static org.junit.Assert.assertFalse;
61 import static org.junit.Assert.assertTrue;
62 import static org.junit.Assume.assumeTrue;
82 final String l_resource =
"../../src/main/resources/";
88 catch (
final Exception l_exception )
90 assumeTrue( MessageFormat.format(
"source directory cannot be read: {0}", l_exception.getMessage() ),
false );
95 IntStream.range( 0, l_languages.length )
105 MessageFormat.format(
109 MessageFormat.format(
110 "language{0}.properties",
113 :
"_" + l_languages[i]
119 catch (
final Exception l_exception )
121 assumeTrue( MessageFormat.format(
"source directory cannot be read: {0}", l_exception.getMessage() ),
false );
134 assumeTrue(
"no languages are defined for checking", !LANGUAGEPROPERY.isEmpty() );
137 final Set<String> l_translation = Collections.unmodifiableSet(
139 .map( i -> i.trim().toLowerCase() )
140 .collect( Collectors.toSet() )
145 final Set<String> l_translationtesting =
new HashSet<>( l_translation );
146 l_translationtesting.removeAll( LANGUAGEPROPERY.keySet() );
148 MessageFormat.format(
149 "configuration defines {1,choice,1#translation|1<translations} {0} that {1,choice,1#is|1<are} not tested",
150 l_translationtesting,
151 l_translationtesting.size()
153 !l_translationtesting.isEmpty()
158 final Set<String> l_translationusing =
new HashSet<>( LANGUAGEPROPERY.keySet() );
159 l_translationusing.removeAll( l_translation );
161 MessageFormat.format(
162 "{1,choice,1#translation|1<translations} {0} {1,choice,1#is|1<are} checked, which will not be used within the package configuration",
164 l_translationusing.size()
166 !l_translationusing.isEmpty()
178 assumeTrue(
"no languages are defined for checking", !LANGUAGEPROPERY.isEmpty() );
180 final Set<String> l_ignoredlabel =
new HashSet<>();
183 final Set<String> l_label = Collections.unmodifiableSet(
184 Files.walk( Paths.get( SEARCHPATH ) )
185 .filter( Files::isRegularFile )
186 .filter( i -> i.toString().endsWith(
".java" ) )
192 l_parser.
visit( JavaParser.parse(
new FileInputStream( i.toFile() ) ), null );
193 return l_parser.
labels().stream();
195 catch (
final IOException l_excpetion )
197 assertTrue( MessageFormat.format(
"io error on file [{0}]: {1}", i, l_excpetion.getMessage() ),
false );
198 return Stream.empty();
200 catch (
final ParseProblemException l_exception )
204 i.toAbsolutePath().toString()
207 FileSystems.getDefault()
209 .getPath( SEARCHPATH )
217 .replace(
".java",
"" )
219 .replace(
"/", CLASSSEPARATOR )
226 System.err.println( MessageFormat.format(
"parsing error on file [{0}]:\n{1}", i, l_exception.getMessage() ) );
227 return Stream.empty();
230 .collect( Collectors.toSet() )
234 assertFalse(
"translation labels are empty, check naming of translation method", l_label.isEmpty() );
237 if ( l_ignoredlabel.size() > 0 )
238 System.err.println( MessageFormat.format(
"labels that starts with {0} are ignored, because parsing errors are occurred", l_ignoredlabel ) );
240 LANGUAGEPROPERY.forEach( ( k, v ) ->
244 final FileInputStream l_stream =
new FileInputStream(
new File( v ) )
247 final Properties l_property =
new Properties();
248 l_property.load( l_stream );
250 final Set<String> l_parseditems =
new HashSet<>( l_label );
251 final Set<String> l_propertyitems = l_property.keySet().parallelStream().map( Object::toString ).collect(
252 Collectors.toSet() );
255 l_parseditems.removeAll( l_propertyitems );
257 MessageFormat.format(
258 "the following {1,choice,1#key|1<keys} in language [{0}] {1,choice,1#is|1<are} not existing within the language file:\n{2}",
260 l_parseditems.size(),
261 StringUtils.join( l_parseditems,
", " )
263 l_parseditems.isEmpty()
268 l_propertyitems.removeAll( l_label );
269 final Set<String> l_ignoredpropertyitems = l_propertyitems.parallelStream()
270 .filter( j -> l_ignoredlabel.parallelStream()
271 .map( j::startsWith )
272 .allMatch( l ->
false )
274 .collect( Collectors.toSet() );
276 MessageFormat.format(
277 "the following {1,choice,1#key|1<keys} in language [{0}] {1,choice,1#is|1<are} not existing within the source code:\n{2}",
279 l_ignoredpropertyitems.size(),
280 StringUtils.join( l_ignoredpropertyitems,
", " )
282 l_ignoredpropertyitems.isEmpty()
285 catch (
final IOException l_exception )
287 assertTrue( MessageFormat.format(
"io exception: {0}", l_exception.getMessage() ),
false );
298 private static class CJavaVistor extends VoidVisitorAdapter<Object>
323 private final Set<String>
m_label =
new HashSet<>();
336 public void visit(
final PackageDeclaration p_package,
final Object p_arg )
338 m_package = p_package.getName().toString();
339 super.visit( p_package, p_arg );
343 public void visit(
final ClassOrInterfaceDeclaration p_class,
final Object p_arg )
345 if ( m_outerclass.isEmpty() )
346 m_outerclass = p_class.getName().toString();
348 m_innerclass = p_class.getName().toString();
350 super.visit( p_class, p_arg );
356 public void visit(
final EnumDeclaration p_enum,
final Object p_arg )
358 if ( m_outerclass.isEmpty() )
359 m_outerclass = p_enum.getName().toString();
361 m_innerclass = p_enum.getName().toString();
363 super.visit( p_enum, p_arg );
369 public void visit(
final MethodCallExpr p_methodcall,
final Object p_arg )
371 final String l_label = this.
label( p_methodcall.toString() );
372 if ( !l_label.isEmpty() )
373 m_label.add( l_label );
375 super.visit( p_methodcall, p_arg );
384 private String
label(
final String p_line )
386 final Matcher l_matcher = LANGUAGEMETHODPATTERN.matcher( p_line );
387 if ( !l_matcher.find() )
390 final String[] l_split = l_matcher.group( 0 ).split(
"," );
391 final String[] l_return =
new String[2];
394 l_return[0] = l_split[0].replace( TRANSLATEMETHODNAME,
"" ).replace(
"(",
"" ).trim();
396 l_return[1] = l_split[1].replace(
")",
"" ).replace(
"\"",
"" ).split(
";" )[0].trim().toLowerCase( Locale.ROOT );
399 "this".equals( l_return[0] )
400 ?
buildlabel( m_package, m_outerclass, m_outerclass, m_innerclass, l_return[1] )
401 :
buildlabel( m_package, m_outerclass, l_return[0].replace(
".class",
"" ).replace( m_package + CLASSSEPARATOR,
"" ),
"", l_return[1] )
402 ).trim().toLowerCase( Locale.ROOT ).replace(
CCommon.
PACKAGEROOT + CLASSSEPARATOR,
"" );
417 private static String
buildlabel(
final String p_package,
final String p_outerclass1,
final String p_outerclass2,
final String p_innerclass,
final String p_label )
419 final String l_outerclass = p_outerclass1.equals( p_outerclass2 )
421 : MessageFormat.format(
"{0}{1}{2}", p_outerclass1, ClassUtils.PACKAGE_SEPARATOR, p_outerclass2 );
423 return MessageFormat.format(
424 "{0}{1}{2}{3}{4}{5}",
425 p_package, ClassUtils.PACKAGE_SEPARATOR,
426 l_outerclass, p_innerclass.isEmpty() ?
"" : ClassUtils.PACKAGE_SEPARATOR,
431 : CLASSSEPARATOR + p_label
static ResourceBundle configuration()
returns the property data of the package
final Set< String > m_label
label set
base test class with helpers
static String [] languages()
list of usable languages
static final String CLASSSEPARATOR
static String buildlabel(final String p_package, final String p_outerclass1, final String p_outerclass2, final String p_innerclass, final String p_label)
returns full qualified class name (inner & outer class)
static final URI SEARCHPATH
search path
void visit(final PackageDeclaration p_package, final Object p_arg)
void visit(final ClassOrInterfaceDeclaration p_class, final Object p_arg)
void visit(final MethodCallExpr p_methodcall, final Object p_arg)
static final String TRANSLATEMETHODNAME
method to translate strings
void testResourceString()
test-case all resource strings
String label(final String p_line)
gets the class name and label name
static URL resourceurl()
returns root path of the resource
void testTranslation()
check package translation configuration versus property items
final Set< String > labels()
returns the translated labels
class for any helper calls
String m_outerclass
outer class name *
static final String PACKAGEROOT
package name
static final Pattern LANGUAGEMETHODPATTERN
reg expression to extract label data
test all resource strings
String m_package
package name *
static URL concaturl(final URL p_base, final String p_string)
concats an URL with a path
String m_innerclass
inner class name *
void visit(final EnumDeclaration p_enum, final Object p_arg)
static final Map< String, URI > LANGUAGEPROPERY
property filenames with language data