You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kh...@apache.org on 2022/09/12 16:28:12 UTC

[maven-shade-plugin] 01/02: WIP. Continued.

This is an automated email from the ASF dual-hosted git repository.

khmarbaise pushed a commit to branch JDK8_IMPROVEMENTS
in repository https://gitbox.apache.org/repos/asf/maven-shade-plugin.git

commit 7bea3744bc4d0213bdadbd0e63ca75471eab8884
Author: Karl Heinz Marbaise <kh...@apache.org>
AuthorDate: Sun Sep 11 18:09:30 2022 +0200

    WIP. Continued.
---
 .../plugins/shade/mojo/PackageRelocation.java      |  7 +++
 .../plugins/shade/relocation/SimpleRelocator.java  | 68 +++++++++++-----------
 .../maven/plugins/shade/DefaultShaderTest.java     |  8 +--
 .../maven/plugins/shade/mojo/ShadeMojoTest.java    |  5 +-
 .../shade/relocation/SimpleRelocatorTest.java      | 40 ++++++-------
 .../resource/ServiceResourceTransformerTest.java   | 16 ++---
 6 files changed, 77 insertions(+), 67 deletions(-)

diff --git a/src/main/java/org/apache/maven/plugins/shade/mojo/PackageRelocation.java b/src/main/java/org/apache/maven/plugins/shade/mojo/PackageRelocation.java
index 9ea92a3..fb5de0a 100644
--- a/src/main/java/org/apache/maven/plugins/shade/mojo/PackageRelocation.java
+++ b/src/main/java/org/apache/maven/plugins/shade/mojo/PackageRelocation.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugins.shade.mojo;
  * under the License.
  */
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -37,6 +38,12 @@ public class PackageRelocation
 
     private boolean rawString;
 
+    public PackageRelocation()
+    {
+        this.includes = Collections.emptyList();
+        this.excludes = Collections.emptyList();
+    }
+
     public String getPattern()
     {
         return pattern;
diff --git a/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java b/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
index df51ea2..3acfafb 100644
--- a/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
+++ b/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
@@ -22,6 +22,7 @@ package org.apache.maven.plugins.shade.relocation;
 import org.codehaus.plexus.util.SelectorUtils;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -117,17 +118,17 @@ public class SimpleRelocator
         this.excludes = normalizePatterns( excludes );
 
         // Don't replace all dots to slashes, otherwise /META-INF/maven/${groupId} can't be matched.
-        if ( includes != null && !includes.isEmpty() )
+        if ( !includes.isEmpty() )
         {
             this.includes.addAll( includes );
         }
 
-        if ( excludes != null && !excludes.isEmpty() )
+        if ( !excludes.isEmpty() )
         {
             this.excludes.addAll( excludes );
         }
 
-        if ( !rawString && this.excludes != null )
+        if ( !rawString && !this.excludes.isEmpty() )
         {
             // Create exclude pattern sets for sources
             for ( String exclude : this.excludes )
@@ -148,54 +149,55 @@ public class SimpleRelocator
 
     private static Set<String> normalizePatterns( Collection<String> patterns )
     {
-        Set<String> normalized = null;
+        if ( patterns.isEmpty() )
+        {
+            return Collections.emptySet();
+        }
 
-        if ( patterns != null && !patterns.isEmpty() )
+        Set<String> normalized = new LinkedHashSet<>();
+        for ( String pattern : patterns )
         {
-            normalized = new LinkedHashSet<>();
-            for ( String pattern : patterns )
+            String classPattern = pattern.replace( '.', '/' );
+            normalized.add( classPattern );
+            // Actually, class patterns should just use 'foo.bar.*' ending with a single asterisk, but some users
+            // mistake them for path patterns like 'my/path/**', so let us be a bit more lenient here.
+            if ( classPattern.endsWith( "/*" ) || classPattern.endsWith( "/**" ) )
             {
-                String classPattern = pattern.replace( '.', '/' );
-                normalized.add( classPattern );
-                // Actually, class patterns should just use 'foo.bar.*' ending with a single asterisk, but some users
-                // mistake them for path patterns like 'my/path/**', so let us be a bit more lenient here.
-                if ( classPattern.endsWith( "/*" ) || classPattern.endsWith( "/**" ) )
-                {
-                    String packagePattern = classPattern.substring( 0, classPattern.lastIndexOf( '/' ) );
-                    normalized.add( packagePattern );
-                }
+                String packagePattern = classPattern.substring( 0, classPattern.lastIndexOf( '/' ) );
+                normalized.add( packagePattern );
             }
         }
-
         return normalized;
+
+//        return patterns.stream()
+//                .map(s -> s.replace( '.', '/' ))
+//                .collect( Collectors.toSet());
+
     }
 
     private boolean isIncluded( String path )
     {
-        if ( includes != null && !includes.isEmpty() )
+        if ( includes.isEmpty() )
         {
-            for ( String include : includes )
-            {
-                if ( SelectorUtils.matchPath( include, path, true ) )
-                {
-                    return true;
-                }
-            }
-            return false;
+            return true;
         }
-        return true;
+
+        return includes.stream()
+                .anyMatch( s -> SelectorUtils.matchPath( s, path, true )  );
     }
 
     private boolean isExcluded( String path )
     {
-        if ( excludes != null && !excludes.isEmpty() )
+        if ( excludes.isEmpty() )
         {
-            for ( String exclude : excludes )
+            return false;
+        }
+
+        for ( String exclude : excludes )
+        {
+            if ( SelectorUtils.matchPath( exclude, path, true ) )
             {
-                if ( SelectorUtils.matchPath( exclude, path, true ) )
-                {
-                    return true;
-                }
+                return true;
             }
         }
         return false;
diff --git a/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java b/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
index a709018..67a0a26 100644
--- a/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
@@ -239,7 +239,7 @@ public class DefaultShaderTest
 
         List<Relocator> relocators = new ArrayList<>();
 
-        relocators.add( new SimpleRelocator( "org.apache.maven.plugins.shade", null, null, null ) );
+        relocators.add( new SimpleRelocator( "org.apache.maven.plugins.shade", null, Collections.emptyList(), Collections.emptyList() ) );
 
         List<ResourceTransformer> resourceTransformers = new ArrayList<>();
 
@@ -294,8 +294,8 @@ public class DefaultShaderTest
 
         List<Relocator> relocators = new ArrayList<>();
 
-        relocators.add( new SimpleRelocator( "org/codehaus/plexus/util/", "_plexus/util/__", null,
-                Collections.<String>emptyList() ) );
+        relocators.add( new SimpleRelocator( "org/codehaus/plexus/util/", "_plexus/util/__", Collections.emptyList(),
+                Collections.emptyList() ) );
 
         List<ResourceTransformer> resourceTransformers = new ArrayList<>();
 
@@ -410,7 +410,7 @@ public class DefaultShaderTest
 
         List<Relocator> relocators = new ArrayList<>();
 
-        relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, null, Arrays.asList( excludes ) ) );
+        relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, Collections.emptyList(), Arrays.asList( excludes ) ) );
 
         List<ResourceTransformer> resourceTransformers = new ArrayList<>();
 
diff --git a/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java b/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
index 0799f3c..60f6a41 100644
--- a/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
@@ -31,6 +31,7 @@ import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -139,7 +140,7 @@ public class ShadeMojoTest
         set.add( new File( getBasedir(), "src/test/jars/test-artifact-1.0-SNAPSHOT.jar" ) );
 
         List<Relocator> relocators = new ArrayList<>();
-        relocators.add( new SimpleRelocator( "org.codehaus.plexus.util", "hidden", null, Arrays.asList(
+        relocators.add( new SimpleRelocator( "org.codehaus.plexus.util", "hidden", Collections.emptyList(), Arrays.asList(
                 "org.codehaus.plexus.util.xml.Xpp3Dom", "org.codehaus.plexus.util.xml.pull.*") ) );
 
         List<ResourceTransformer> resourceTransformers = new ArrayList<>();
@@ -283,7 +284,7 @@ public class ShadeMojoTest
 
         List<Relocator> relocators = new ArrayList<>();
 
-        relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, null, Arrays.asList(
+        relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, Collections.emptyList(), Arrays.asList(
                 "org/codehaus/plexus/util/xml/Xpp3Dom", "org/codehaus/plexus/util/xml/pull.*") ) );
 
         List<ResourceTransformer> resourceTransformers = new ArrayList<>();
diff --git a/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java b/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
index 699d1b3..33dd7d7 100644
--- a/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
@@ -41,7 +41,7 @@ public class SimpleRelocatorTest
     @Test
     public void testNoNpeRelocateClass()
     {
-        new SimpleRelocator( "foo", "bar", null, null, true ).relocateClass( "foo" );
+        new SimpleRelocator( "foo", "bar", Collections.emptyList(), Collections.emptyList(), true ).relocateClass( "foo" );
     }
 
     @Test
@@ -49,7 +49,7 @@ public class SimpleRelocatorTest
     {
         SimpleRelocator relocator;
 
-        relocator = new SimpleRelocator( "org.foo", null, null, null );
+        relocator = new SimpleRelocator( "org.foo", null, Collections.emptyList(), Collections.emptyList() );
         assertTrue( relocator.canRelocatePath( "org/foo/Class" ) );
         assertTrue( relocator.canRelocatePath( "org/foo/Class.class" ) );
         assertTrue( relocator.canRelocatePath( "org/foo/bar/Class" ) );
@@ -59,7 +59,7 @@ public class SimpleRelocatorTest
         assertFalse( relocator.canRelocatePath( "org/Foo/Class" ) );
         assertFalse( relocator.canRelocatePath( "org/Foo/Class.class" ) );
 
-        relocator = new SimpleRelocator( "org.foo", null, null, Arrays.asList(
+        relocator = new SimpleRelocator( "org.foo", null, Collections.emptyList(), Arrays.asList(
                 "org.foo.Excluded", "org.foo.public.*", "org.foo.Public*Stuff") );
         assertTrue( relocator.canRelocatePath( "org/foo/Class" ) );
         assertTrue( relocator.canRelocatePath( "org/foo/Class.class" ) );
@@ -83,13 +83,13 @@ public class SimpleRelocatorTest
     {
         SimpleRelocator relocator;
 
-        relocator = new SimpleRelocator( "org.foo", null, null, null );
+        relocator = new SimpleRelocator( "org.foo", null, Collections.emptyList(), Collections.emptyList() );
         assertTrue( relocator.canRelocateClass( "org.foo.Class" ) );
         assertTrue( relocator.canRelocateClass( "org.foo.bar.Class" ) );
         assertFalse( relocator.canRelocateClass( "com.foo.bar.Class" ) );
         assertFalse( relocator.canRelocateClass( "org.Foo.Class" ) );
 
-        relocator = new SimpleRelocator( "org.foo", null, null, Arrays.asList(
+        relocator = new SimpleRelocator( "org.foo", null, Collections.emptyList(), Arrays.asList(
                 "org.foo.Excluded", "org.foo.public.*", "org.foo.Public*Stuff") );
         assertTrue( relocator.canRelocateClass( "org.foo.Class" ) );
         assertTrue( relocator.canRelocateClass( "org.foo.excluded" ) );
@@ -107,10 +107,10 @@ public class SimpleRelocatorTest
     {
         SimpleRelocator relocator;
 
-        relocator = new SimpleRelocator( "org/foo", null, null, null, true );
+        relocator = new SimpleRelocator( "org/foo", null, Collections.emptyList(), Collections.emptyList(), true );
         assertTrue( relocator.canRelocatePath( "(I)org/foo/bar/Class;" ) );
 
-        relocator = new SimpleRelocator( "^META-INF/org.foo.xml$", null, null, null, true );
+        relocator = new SimpleRelocator( "^META-INF/org.foo.xml$", null, Collections.emptyList(), Collections.emptyList(), true );
         assertTrue( relocator.canRelocatePath( "META-INF/org.foo.xml" ) );
     }
 
@@ -118,14 +118,14 @@ public class SimpleRelocatorTest
     @Test
     public void testCanRelocateAbsClassPath()
     {
-        SimpleRelocator relocator = new SimpleRelocator( "org.apache.velocity", "org.apache.momentum", null, null );
+        SimpleRelocator relocator = new SimpleRelocator( "org.apache.velocity", "org.apache.momentum", Collections.emptyList(), Collections.emptyList() );
         assertEquals("/org/apache/momentum/mass.properties", relocator.relocatePath( "/org/apache/velocity/mass.properties" ) );
     }
 
     @Test
     public void testCanRelocateAbsClassPathWithExcludes()
     {
-        SimpleRelocator relocator = new SimpleRelocator( "org/apache/velocity", "org/apache/momentum", null,
+        SimpleRelocator relocator = new SimpleRelocator( "org/apache/velocity", "org/apache/momentum", Collections.emptyList(),
                                                          Arrays.asList( "org/apache/velocity/excluded/*" ) );
         assertTrue( relocator.canRelocatePath( "/org/apache/velocity/mass.properties" ) );
         assertTrue( relocator.canRelocatePath( "org/apache/velocity/mass.properties" ) );
@@ -137,7 +137,7 @@ public class SimpleRelocatorTest
     public void testCanRelocateAbsClassPathWithIncludes()
     {
         SimpleRelocator relocator = new SimpleRelocator( "org/apache/velocity", "org/apache/momentum",
-                                                         Arrays.asList( "org/apache/velocity/included/*" ), null );
+                                                         Arrays.asList( "org/apache/velocity/included/*" ), Collections.emptyList() );
         assertFalse( relocator.canRelocatePath( "/org/apache/velocity/mass.properties" ) );
         assertFalse( relocator.canRelocatePath( "org/apache/velocity/mass.properties" ) );
         assertTrue( relocator.canRelocatePath( "/org/apache/velocity/included/mass.properties" ) );
@@ -149,10 +149,10 @@ public class SimpleRelocatorTest
     {
         SimpleRelocator relocator;
 
-        relocator = new SimpleRelocator( "org.foo", null, null, null );
+        relocator = new SimpleRelocator( "org.foo", null, Collections.emptyList(), Collections.emptyList() );
         assertEquals( "hidden/org/foo/bar/Class.class", relocator.relocatePath( "org/foo/bar/Class.class" ) );
 
-        relocator = new SimpleRelocator( "org.foo", "private.stuff", null, null );
+        relocator = new SimpleRelocator( "org.foo", "private.stuff", Collections.emptyList(), Collections.emptyList() );
         assertEquals( "private/stuff/bar/Class.class", relocator.relocatePath( "org/foo/bar/Class.class" ) );
     }
 
@@ -161,10 +161,10 @@ public class SimpleRelocatorTest
     {
         SimpleRelocator relocator;
 
-        relocator = new SimpleRelocator( "org.foo", null, null, null );
+        relocator = new SimpleRelocator( "org.foo", null, Collections.emptyList(), Collections.emptyList() );
         assertEquals( "hidden.org.foo.bar.Class", relocator.relocateClass( "org.foo.bar.Class" ) );
 
-        relocator = new SimpleRelocator( "org.foo", "private.stuff", null, null );
+        relocator = new SimpleRelocator( "org.foo", "private.stuff", Collections.emptyList(), Collections.emptyList() );
         assertEquals( "private.stuff.bar.Class", relocator.relocateClass( "org.foo.bar.Class" ) );
     }
 
@@ -173,10 +173,10 @@ public class SimpleRelocatorTest
     {
         SimpleRelocator relocator;
 
-        relocator = new SimpleRelocator( "Lorg/foo", "Lhidden/org/foo", null, null, true );
+        relocator = new SimpleRelocator( "Lorg/foo", "Lhidden/org/foo", Collections.emptyList(), Collections.emptyList(), true );
         assertEquals( "(I)Lhidden/org/foo/bar/Class;", relocator.relocatePath( "(I)Lorg/foo/bar/Class;" ) );
 
-        relocator = new SimpleRelocator( "^META-INF/org.foo.xml$", "META-INF/hidden.org.foo.xml", null, null, true );
+        relocator = new SimpleRelocator( "^META-INF/org.foo.xml$", "META-INF/hidden.org.foo.xml", Collections.emptyList(), Collections.emptyList(), true );
         assertEquals( "META-INF/hidden.org.foo.xml", relocator.relocatePath( "META-INF/org.foo.xml" ) );
     }
 
@@ -184,7 +184,7 @@ public class SimpleRelocatorTest
     public void testRelocateMavenFiles()
     {
         SimpleRelocator relocator =
-            new SimpleRelocator( "META-INF/maven", "META-INF/shade/maven", null,
+            new SimpleRelocator( "META-INF/maven", "META-INF/shade/maven", Collections.emptyList(),
                                  Collections.singletonList( "META-INF/maven/com.foo.bar/artifactId/pom.*" ) );
         assertFalse( relocator.canRelocatePath( "META-INF/maven/com.foo.bar/artifactId/pom.properties" ) );
         assertFalse( relocator.canRelocatePath( "META-INF/maven/com.foo.bar/artifactId/pom.xml" ) );
@@ -277,11 +277,11 @@ public class SimpleRelocatorTest
                 Arrays.asList( "foo.bar", "zot.baz" ),
                 Arrays.asList( "irrelevant.exclude", "org.apache.maven.exclude1", "org.apache.maven.sub.exclude2" ) );
         // Make sure not to replace variables 'io' and 'ioInput', package 'java.io'
-        SimpleRelocator ioRelocator = new SimpleRelocator( "io", "shaded.io", null, null );
+        SimpleRelocator ioRelocator = new SimpleRelocator( "io", "shaded.io", Collections.emptyList(), Collections.emptyList() );
         // Check corner case which was not working in PR #100
-        SimpleRelocator asmRelocator = new SimpleRelocator( "org.objectweb.asm", "aj.org.objectweb.asm", null, null );
+        SimpleRelocator asmRelocator = new SimpleRelocator( "org.objectweb.asm", "aj.org.objectweb.asm", Collections.emptyList(), Collections.emptyList() );
         // Make sure not to replace 'foo' package by path-like 'shaded/foo'
-        SimpleRelocator fooRelocator = new SimpleRelocator( "foo", "shaded.foo", null, Arrays.asList( "foo.bar" ) );
+        SimpleRelocator fooRelocator = new SimpleRelocator( "foo", "shaded.foo", Collections.emptyList(), Arrays.asList( "foo.bar" ) );
         assertEquals(
             relocatedFile,
             fooRelocator.applyToSourceContent(
diff --git a/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java b/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java
index f58c1a0..bdd8add 100644
--- a/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java
@@ -29,7 +29,6 @@ import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.jar.JarEntry;
@@ -52,7 +51,8 @@ public class ServiceResourceTransformerTest {
     @Test
     public void relocatedClasses() throws Exception {
         SimpleRelocator relocator =
-            new SimpleRelocator( "org.foo", "borg.foo", null, Arrays.asList( "org.foo.exclude.*" ) );
+            new SimpleRelocator( "org.foo", "borg.foo", Collections.emptyList(),
+                    Collections.singletonList( "org.foo.exclude.*" ) );
         relocators.add( relocator );
 
         String content = "org.foo.Service\norg.foo.exclude.OtherService\n";
@@ -76,7 +76,7 @@ public class ServiceResourceTransformerTest {
             JarEntry jarEntry = jarFile.getJarEntry( contentResourceShaded );
             assertNotNull( jarEntry );
             try ( InputStream entryStream = jarFile.getInputStream( jarEntry ) ) {
-                String xformedContent = IOUtils.toString( entryStream, "utf-8" );
+                String xformedContent = IOUtils.toString( entryStream, StandardCharsets.UTF_8 );
                 assertEquals( "borg.foo.Service" + NEWLINE
                     + "org.foo.exclude.OtherService" + NEWLINE, xformedContent );
             } finally {
@@ -90,7 +90,7 @@ public class ServiceResourceTransformerTest {
     @Test
     public void mergeRelocatedFiles() throws Exception {
         SimpleRelocator relocator =
-                new SimpleRelocator( "org.foo", "borg.foo", null, Collections.singletonList("org.foo.exclude.*"));
+                new SimpleRelocator( "org.foo", "borg.foo", Collections.emptyList(), Collections.singletonList("org.foo.exclude.*"));
         relocators.add( relocator );
 
         String content = "org.foo.Service" + NEWLINE + "org.foo.exclude.OtherService" + NEWLINE;
@@ -133,11 +133,11 @@ public class ServiceResourceTransformerTest {
     @Test
     public void concatanationAppliedMultipleTimes() throws Exception {
         SimpleRelocator relocator =
-            new SimpleRelocator( "org.eclipse", "org.eclipse1234", null, null );
+            new SimpleRelocator( "org.eclipse", "org.eclipse1234", Collections.emptyList(), Collections.emptyList() );
         relocators.add( relocator );
         
         String content = "org.eclipse.osgi.launch.EquinoxFactory\n";
-        byte[] contentBytes = content.getBytes( "UTF-8" );
+        byte[] contentBytes = content.getBytes( StandardCharsets.UTF_8 );
         InputStream contentStream = new ByteArrayInputStream( contentBytes );
         String contentResource = "META-INF/services/org.osgi.framework.launch.FrameworkFactory";
 
@@ -168,7 +168,7 @@ public class ServiceResourceTransformerTest {
 
     @Test
     public void concatenation() throws Exception {
-        SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, null);
+        SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", Collections.emptyList(), Collections.emptyList());
         relocators.add( relocator );
         
         String content = "org.foo.Service\n";
@@ -199,7 +199,7 @@ public class ServiceResourceTransformerTest {
             JarEntry jarEntry = jarFile.getJarEntry( contentResource );
             assertNotNull( jarEntry );
             try ( InputStream entryStream = jarFile.getInputStream( jarEntry ) ) {
-                String xformedContent = IOUtils.toString(entryStream, "utf-8");
+                String xformedContent = IOUtils.toString(entryStream, StandardCharsets.UTF_8 );
                 // must be two lines, with our two classes.
                 String[] classes = xformedContent.split("\r?\n");
                 boolean h1 = false;