Parameterized Factories


A parameterized Factory has additional parameters that initiate replacement of specified variables and/or text in code. In other words, such a Factory clones code from the original source (whatever SCM system is used), and replaces variables in the resulting Factory files, according to a replacement algorithm and chosen replacement mode.

Adding such a parameter is performed in two simple steps:

  • Generating variables replacement
  • Adding it to factory

If a Factory is encoded, replacement parameters are to be added to JSON when using our REST API. If a Factory is non-encoded, JSON should be encoded and then added to a Factory URL just like any other parameter.

Create Replacement Parameters

The replacement JSON has the following attributes:

  • “files” specifies path patterns for search (pattern support wildcard as last path segment). Path should start from project root folder
  • “entries” that includes:
  • “find” – a variable that should be replaced with certain value
  • “replace” – replacement value for a chosen variable
  • “replacemode” (optional) – see definition below

Replacement Mode

A “replacemode” parameter indicates which replacement algorithm should be applied:

  • variable_singlepass
  • text_multipass

variable_singlepass – In this mode variables that start with ‘$’ sign and are enclosed with curly brackets {} will be searched. For example, to replace variable VAR_1_NAME in the resulting code, one should put ${VAR_1_NAME} variable in the source code. In such a way, ${VAR_1_NAME} will become VAR_1_NAME.

text_multipass – In this mode plain text will be searched. For example, in VAR_1_NAME should be replaced with VAR_2_NAME in a multipass mode, ${VAR_1_NAME} will become ${VAR_2_NAME}. Implementation of this method is slower due to fact that the entire file content needs to be scanned.

It is possible to combine two replacement methods, but priority is always given to a singlepass one. If no replacement method is identified, replacement will be performed in a singlepass mode.
In source code, variables should be placed inside curly brackets with a leading $ – ${VARIABLE}. As a Factory URL parameter, variables should be used without it in a JSON file:

[
   {
      "files":[
         "src/main/resources/*"
      ],
      "entries":[
         {
            "find":"OLD_VALUE",
            "replace":"NEW_VALUE"
         }
      ]
   },
   {
      "files":[
         "src/main/resources/MyClass.java",
         "src/main/resources/MyClass1.java"
      ],
      "entries":[
         {
            "find":"OLD_VALUE_2",
            "replace":"NEW_VALUE_2"
         },
         {
            "find":"OLD_VALUE_3",
            "replace":"NEW_VALUE_3"
         }
      ]
   }
]

Original Java class from the source project:

/**
 * @author <a href="mailto:${AUTHOR_EMAIL}">${AUTHOR_NAME}</a>
 * @version $Id: 16.12.13 ${AUTHOR} $
 */
public class MyClass {
    private static final String VARIABLE_1 = "${OLD_VALUE_2}";
    private static final String VARIABLE_2 = "${OLD_VALUE_3}"
    private static final String VARIABLE_3 = "${OLD_VALUE}";
}

Resulting code in a temporary workspace:

/**
 * @author <a href="mailto:${AUTHOR_EMAIL}">${AUTHOR_NAME}</a>
 * @version $Id: 16.12.13 ${AUTHOR} $
 */
public class MyClass {
    private static final String VARIABLE_1 = "NEW_VALUE_2";
    private static final String VARIABLE_2 = "NEW_VALUE_3";
    private static final String VARIABLE_3 = "NEW_VALUE";
}

Add Replacement Parameters to Encoded Factory

Custom encoded Factories can be created only using our REST API. Here’s an example of a JSON used to create an encoded Factory that includes replacement parameters:

----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="factoryUrl"
Content-Type: application/json{
   "v":"1.1",
   "vcs":"git",
   "vcsurl":"http://codenvy.com/git/c4/1a/b9/workspace0nzgq70h7qpz7epd/SpringDemo",
   "commitid":"28d0af4bc7c1c82bfeba0b02f74de44f68bb37fb",
   "projectattributes":{
      "pname":"SpringDemo",
      "ptype":"Spring"
   },
   "action":"openproject",
   "style":"Vertical,Dark",
   "description":"This is description of Spring project",
   "contactmail":"developer@codenvy.com",
   "author":"Tyler Jewell",
   "openfile":"/src/main/java/test/Product.java",
   "orgid":"org1q2w3e56rgh8",
   "affiliateid":"affiliate255f8fd47f",
   "keepvcsinfo":"true",
   "variables":[
      {
         "files":[
            "src/main/resources/*"
         ],
         "entries":[
            {
               "find":"OLD_VALUE",
               "replace":"NEW_VALUE"
            }
         ]
      },
      {
         "files":[
            "src/main/resources/consts.properties",
            "src/main/resources/consts2.properties"
         ],
         "entries":[
            {
               "find":"OLD_VALUE_2",
               "replace":"NEW_VALUE_2"
            },
            {
               "find":"OLD_VALUE_3",
               "replace":"NEW_VALUE_3"
            }
         ]
      }
   ]
}

----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="image"; filename="logo.JPG"
Content-Type: image/jpeg

(the binary contents of the image)
----WebKitFormBoundaryE19zNvXGzXaLvS5C

Add Replacement Parameters to Non-Encoded Factory

Once you define your replacement parameters, you have to encode JSON values into a URL friendly format, which will look like:
%5B%7B%22files%22%3A%5B%22src%2Fmain%2Fresources%2F*%22%5D%2C%22entries%22%3A%5B%7B%22find%22%3A%22OLD_VALUE%22%2C%22replace%22%3A%22NEW_VALUE%22%7D%5D%7D%2C%7B%22files%22%3A%5B%22src%2Fmain%2Fresources%2Fconsts.properties%22%2C%22src%2Fmain%2Fresources%2Fconsts2.properties%22%5D%2C%22entries%22%3A%5B%7B%22find%22%3A%22OLD_VALUE_2%22%2C%22replace%22%3A%22NEW_VALUE_2%22%7D%2C%7B%22find%22%3A%22OLD_VALUE_3%22%2C%22replace%22%3A%22NEW_VALUE_3%22%7D%5D%7D%5D

Then, add these parameters to a Factory URL:
https://codenvy.com/factory?v=1.0&pname=Sample-Android&wname=codenvy-factories&vcs=git&vcsurl=http%3A%2F%2Fcodenvy.com%2Fgit%2F04%2F0f%2F7f%2Fworkspacegcpv6cdxy1q34n1i%2FSample-Android&idcommit=2e0a2ca39856d8f5a34c32b2838918a07427ce49&action=openproject&ptype=Android&openfile=AndroidManifest.xml&variables=%5B%7B%22files%22%3A%5B%22src%2Fmain%2Fresources%2F*%22%5D%2C%22entries%22%3A%5B%7B%22find%22%3A%22OLD_VALUE%22%2C%22replace%22%3A%22NEW_VALUE%22%7D%5D%7D%2C%7B%22files%22%3A%5B%22src%2Fmain%2Fresources%2Fconsts.properties%22%2C%22src%2Fmain%2Fresources%2Fconsts2.properties%22%5D%2C%22entries%22%3A%5B%7B%22find%22%3A%22OLD_VALUE_2%22%2C%22replace%22%3A%22NEW_VALUE_2%22%7D%2C%7B%22find%22%3A%22OLD_VALUE_3%22%2C%22replace%22%3A%22NEW_VALUE_3%22%7D%5D%7D%5D

Description of Glob Format

Path format can be given as a glob pattern. But what is a glob? A glob pattern is specified as a string and is matched against other strings, such as directory or file names. Glob syntax follows several simple rules:

Syntax PatternExplanation
*Matches any number of characters (including none)
**Works like * but crosses directory boundaries. This syntax is generally used for matching complete paths
?Matches the exact character
{sun,moon,stars} Matches "sun", "moon", or "stars".
{temp*,tmp*}Matches all strings beginning with "temp" or "tmp"
[aeiou]Matches any lowercase vowel.
[0-9]Matches any digit (dash is used to denote a range of characters)
[A-Z] Matches any uppercase letter
[a-z,A-Z]Matches any uppercase or lowercase letter
[*,?,\]*, ?, and \ will match themselves

To match *, ?, or any other other special characters, use backslash character – \. For example: \\ matches a single backslash, and \? matches the question mark.

Example of usage:

  • *.html – Matches all strings that end in .html
  • ??? – Matches all strings with exactly three letters or digits
  • *[0-9]* – Matches all strings containing a numeric value
  • *.{htm,html,pdf} – Matches any string ending with .htm, .html or .pdf
  • a?*.java – Matches any string beginning with a, followed by at least one letter or digit, and ending with .java
  • {foo*,*[0-9]*} – Matches any string beginning with foo or any string containing a numeric value
File PatternVariable To FindReplacement ValueDescription
src/main/java/awesome/TestClass.javaAUTHOR
AUTHOR_EMAIL
AUTHOR_NAME
NickName
user@codenvy.com
User Name
Find variables ${AUTHOR}, ${AUTHOR_EMAIL}, ${AUTHOR_NAME} in TestClass.java and replace them with given values.
Consts.javaPROJECT_ID
PROJECT_NUMBER
someID123
someProjectNumber123
Find all files in a project with name Consts.java and perform replacement for variables ${PROJECT_ID} and ${PROJECT_NUMBER} with given values.
*Test[1-2].javaAUTHOR
AUTHOR_EMAIL
AUTHOR_NAME
NickName
user@codenvy.com
User Name
Find all files in a project that contain "Test" and char '1' or '2' in their names with ".java" ending. It means that only Test1.java and Test2.java files will match this pattern. Variables ${AUTHOR}, ${AUTHOR_EMAIL}, ${AUTHOR_NAME} will be replaced with given values.
{pom.xm*,*age.html}GROUP_ID
ARTIFACT_ID
PROJECT_VERSION
AUTHOR
VERSION
Codenvy
com.codenvy.factory.sample
0.1-SNAPSHOT
Author Name
0.1-SNAPSHOT
Find all files with names that start with "pom.xm" and end in "age.html". It means that files pom.xml and page.html will match a current project. Replacement of variables ${GROUPD_ID}, ${ARTIFACT_ID}, ${PROJECT_VERSION}, ${AUTHOR}, ${VERSION} will be performed.