66
77import com .cloudinary .transformation .AbstractLayer ;
88import com .cloudinary .transformation .Condition ;
9+ import com .cloudinary .transformation .Expression ;
910import com .cloudinary .utils .ObjectUtils ;
1011import com .cloudinary .utils .StringUtils ;
1112
@@ -365,6 +366,25 @@ public Transformation ifCondition(String condition) {
365366 return param ("if" , condition );
366367 }
367368
369+
370+ /**
371+ * Define a conditional transformation
372+ * @param expression a condition
373+ * @return the transformation for chaining
374+ */
375+ public Transformation ifCondition (Expression expression ) {
376+ return ifCondition (expression .toString ());
377+ }
378+
379+ /**
380+ * Define a conditional transformation
381+ * @param condition a condition
382+ * @return the transformation for chaining
383+ */
384+ public Transformation ifCondition (Condition condition ) {
385+ return ifCondition (condition .toString ());
386+ }
387+
368388 public Transformation ifElse () {
369389 chain ();
370390 return param ("if" , "else" );
@@ -530,24 +550,32 @@ public String generate(Map options) {
530550 String dpr = ObjectUtils .asString (options .get ("dpr" ), null == defaultDPR ? null : defaultDPR .toString ());
531551
532552 SortedMap <String , String > params = new TreeMap <String , String >();
533- params .put ("a" , angle );
553+
554+ params .put ("a" , Expression .normalize (angle ));
555+ params .put ("ar" , Expression .normalize ( options .get ("aspect_ratio" )));
534556 params .put ("b" , background );
535557 params .put ("c" , crop );
536558 params .put ("co" , color );
537- params .put ("dpr" , dpr );
559+ params .put ("dpr" , Expression . normalize ( dpr ) );
538560 params .put ("du" , duration );
539561 params .put ("eo" , endOffset );
540562 params .put ("fl" , flags );
541- params .put ("h" , height );
563+ params .put ("h" , Expression .normalize (height ));
564+ params .put ("o" , Expression .normalize ( options .get ("opacity" )));
565+ params .put ("q" , Expression .normalize ( options .get ("quality" )));
566+ params .put ("q" , Expression .normalize ( options .get ("quality" )));
567+ params .put ("r" , Expression .normalize ( options .get ("radius" )));
542568 params .put ("so" , startOffset );
543569 params .put ("t" , namedTransformation );
544570 params .put ("vc" , videoCodec );
545- params .put ("w" , width );
571+ params .put ("w" , Expression .normalize (width ));
572+ params .put ("x" , Expression .normalize ( options .get ("x" )));
573+ params .put ("y" , Expression .normalize ( options .get ("y" )));
574+ params .put ("z" , Expression .normalize ( options .get ("zoom" )));
546575
547576 String [] simple_params = new String []{
548577 "ac" , "audio_codec" ,
549578 "af" , "audio_frequency" ,
550- "ar" , "aspect_ratio" ,
551579 "bo" , "border" ,
552580 "br" , "bit_rate" ,
553581 "cs" , "color_space" ,
@@ -558,21 +586,39 @@ public String generate(Map options) {
558586 "f" , "fetch_format" ,
559587 "g" , "gravity" ,
560588 "l" , "overlay" ,
561- "o" , "opacity" ,
562589 "p" , "prefix" ,
563590 "pg" , "page" ,
564- "q" , "quality" ,
565- "r" , "radius" ,
566591 "u" , "underlay" ,
567- "vs" , "video_sampling" ,
568- "x" , "x" ,
569- "y" , "y" ,
570- "z" , "zoom" };
592+ "vs" , "video_sampling"
593+ };
571594
572595 for (int i = 0 ; i < simple_params .length ; i += 2 ) {
573596 params .put (simple_params [i ], ObjectUtils .asString (options .get (simple_params [i + 1 ])));
574597 }
575598 List <String > components = new ArrayList <String >();
599+
600+ String ifValue = (String ) options .get ("if" );
601+ if (ifValue != null ){
602+ components .add (0 , "if_" + Expression .normalize (ifValue ));
603+ }
604+
605+ List <String > varParams = new ArrayList <String >();
606+ for ( Object k : options .keySet ()) {
607+ String key = (String ) k ;
608+ if (key .matches ("^\\ $[a-zA-Z0-9]+$" )) {
609+ varParams .add (key + "_" + ObjectUtils .asString (options .get (k )));
610+ }
611+ }
612+
613+ String variables = processVar ((Expression []) options .get ("variables" ));
614+ if (variables != null ) {
615+ varParams .add (variables );
616+ }
617+
618+ if (varParams != null && !varParams .isEmpty ()) {
619+ components .add (StringUtils .join (varParams , "," ));
620+ }
621+
576622 for (Map .Entry <String , String > param : params .entrySet ()) {
577623 if (StringUtils .isNotBlank (param .getValue ())) {
578624 components .add (param .getKey () + "_" + param .getValue ());
@@ -582,14 +628,9 @@ public String generate(Map options) {
582628 if (raw_transformation != null ) {
583629 components .add (raw_transformation );
584630 }
585-
586- String ifValue = (String ) options .get ("if" );
587- if (ifValue != null ){
588- components .add (0 , "if_" + new Condition (ifValue ).toString ());
589- }
590-
591631 if (!components .isEmpty ()) {
592- transformations .add (StringUtils .join (components , "," ));
632+ final String joined = StringUtils .join (components , "," );
633+ transformations .add (Expression .normalize (joined ));
593634 }
594635
595636 if (isResponsive ) {
@@ -607,6 +648,17 @@ public String generate(Map options) {
607648 return StringUtils .join (transformations , "/" );
608649 }
609650
651+ private String processVar (Expression [] variables ) {
652+ if (variables == null ) {
653+ return null ;
654+ }
655+ List <String > s = new ArrayList <String >(variables .length );
656+ for (Expression variable : variables ) {
657+ s .add (variable .toString ());
658+ }
659+ return StringUtils .join (s , "," );
660+ }
661+
610662 /**
611663 * Check if the value is a float >= 1
612664 * @param value
@@ -710,4 +762,23 @@ private static String processVideoCodecParam(Object param) {
710762 return outParam .toString ();
711763 }
712764
765+ /**
766+ * Add a variable assignment. Each call to this method will add a new variable assignments, but the order of the assignments may change. To enforce a particular order, use {@link #variables(Expression...)}
767+ * @param name the name of the variable
768+ * @param value the value to assign to the variable
769+ * @return this for chaining
770+ */
771+ public Transformation variable (String name , Object value ) {
772+ return param (name , value );
773+ }
774+
775+ /**
776+ * Add a sequence of variable assignments. The order of the assignments will be honored.
777+ * @param variables variable expressions
778+ * @return this for chaining
779+ */
780+ public Transformation variables (Expression ...variables ) {
781+ return param ("variables" , variables );
782+ }
783+
713784}
0 commit comments