22
33import java .net .URI ;
44import java .net .URISyntaxException ;
5+ import java .util .ArrayList ;
6+ import java .util .Collection ;
57import java .util .Map ;
68import java .util .regex .Matcher ;
79import java .util .regex .Pattern ;
810
911import com .github .dockerjava .api .DockerClientException ;
12+ import com .google .common .base .Function ;
1013import com .google .common .base .Objects ;
1114import com .google .common .base .Optional ;
15+ import com .google .common .base .Predicate ;
16+ import com .google .common .collect .Collections2 ;
17+ import org .apache .commons .lang .StringUtils ;
1218
1319/**
1420 * A statement present in a dockerfile.
@@ -72,36 +78,42 @@ public String toString() {
7278 */
7379 public static class Add extends DockerfileStatement <Add > {
7480
75- private static final Pattern ADD_OR_COPY_PATTERN = Pattern .compile ("^(ADD|COPY) \\ s+(.*) \\ s+(.*)$ " );
81+ private static final Pattern ARGUMENT_TOKENIZER = Pattern .compile ("(?: \" [^ \" ]+ \" )|( \\ S+) " );
7682
77- public final String source ;
83+ public final Collection < String > sources ;
7884
7985 public final String destination ;
8086
81- private Add (String source , String destination ) {
82- this .source = source ;
87+ private Add (Collection < String > sources , String destination ) {
88+ this .sources = sources ;
8389 this .destination = destination ;
8490 }
8591
86- private Add (final Matcher matcher ) {
87- source = matcher .group (2 );
88- destination = matcher .group (3 );
89- }
90-
9192 @ Override
92- public Add transform (Map <String , String > env ) {
93- String resource = filterForEnvironmentVars (env , source ).trim ();
94- return new Add (resource , destination );
95- }
96-
97- public boolean isFileResource () {
98- URI uri ;
99- try {
100- uri = new URI (source );
101- } catch (URISyntaxException e ) {
102- return false ;
103- }
104- return uri .getScheme () == null || "file" .equals (uri .getScheme ());
93+ public Add transform (final Map <String , String > env ) {
94+ Collection <String > resources = Collections2 .transform (sources , new Function <String , String >() {
95+ @ Override
96+ public String apply (String source ) {
97+ return filterForEnvironmentVars (env , source ).trim ();
98+ }
99+ });
100+ return new Add (resources , destination );
101+ }
102+
103+ public Iterable <String > getFileResources () {
104+ return Collections2 .filter (sources , new Predicate <String >() {
105+
106+ @ Override
107+ public boolean apply (String source ) {
108+ URI uri ;
109+ try {
110+ uri = new URI (source );
111+ } catch (URISyntaxException e ) {
112+ return false ;
113+ }
114+ return uri .getScheme () == null || "file" .equals (uri .getScheme ());
115+ }
116+ });
105117 }
106118
107119 /**
@@ -112,21 +124,37 @@ public boolean isFileResource() {
112124 * @return optional typed item.
113125 */
114126 public static Optional <Add > create (String statement ) {
115- Matcher matcher = ADD_OR_COPY_PATTERN .matcher (statement .trim ());
116- if (!matcher .find ()) {
127+ Matcher argumentMatcher = ARGUMENT_TOKENIZER .matcher (statement .trim ());
128+
129+ if (!argumentMatcher .find ()) {
117130 return Optional .absent ();
118131 }
119132
120- if (matcher .groupCount () != 3 ) {
133+ String commandName = argumentMatcher .group ();
134+ if (!(StringUtils .equals (commandName , "ADD" ) || StringUtils .equals (commandName , "COPY" ))) {
135+ return Optional .absent ();
136+ }
137+
138+ String lastToken = null ;
139+ Collection <String > sources = new ArrayList <>();
140+
141+ while (argumentMatcher .find ()) {
142+ if (lastToken != null ) {
143+ sources .add (lastToken );
144+ }
145+ lastToken = argumentMatcher .group ().replaceAll ("(^\" )|(\" $)" , "" );
146+ }
147+
148+ if (sources .isEmpty ()) {
121149 throw new DockerClientException ("Wrong ADD or COPY format" );
122150 }
123151
124- return Optional .of (new Add (matcher ));
152+ return Optional .of (new Add (sources , lastToken ));
125153 }
126154
127155 @ Override
128156 public String toString () {
129- return Objects .toStringHelper (this ).add ("source " , source ).add ("destination" , destination ).toString ();
157+ return Objects .toStringHelper (this ).add ("sources " , sources ).add ("destination" , destination ).toString ();
130158 }
131159 }
132160
0 commit comments