diff --git a/.travis.yml b/.travis.yml
index c37f80d3..62e87025 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,14 @@ branches:
only:
- develop
-install: mvn install
+before_install:
+ # Importing key used to sign jars, necessary for release artifacts deployment in Maven Central
+ - openssl aes-256-cbc -K $encrypted_dd05710e44e2_key -iv $encrypted_dd05710e44e2_iv -in secring.gpg.enc -out secring.gpg -d
+ - gpg --import secring.gpg
+
+install:
+ # Building and deploying artifacts to Maven Central
+ - mvn -B -s settings.xml deploy -Possrh
after_success:
# Installing Codacy code coverage reporter upload tool
@@ -22,5 +29,3 @@ after_success:
- java -cp ccr.jar com.codacy.CodacyCoverageReporter -l Java -r ./butterfly-metrics-couchdb/target/site/cobertura/coverage.xml --projectToken $CODACY_PROJECT_TOKEN
- java -cp ccr.jar com.codacy.CodacyCoverageReporter -l Java -r ./butterfly-metrics-file/target/site/cobertura/coverage.xml --projectToken $CODACY_PROJECT_TOKEN
- java -cp ccr.jar com.codacy.CodacyCoverageReporter -l Java -r ./butterfly-utilities/target/site/cobertura/coverage.xml --projectToken $CODACY_PROJECT_TOKEN
- # Deploying artifacts to Maven Central
- - mvn -B -s settings.xml -DskipTests=true -Dcobertura.skip deploy -Possrh
\ No newline at end of file
diff --git a/butterfly-cli-package/pom.xml b/butterfly-cli-package/pom.xml
index d9adac4a..f41e3836 100644
--- a/butterfly-cli-package/pom.xml
+++ b/butterfly-cli-package/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-cli/pom.xml b/butterfly-cli/pom.xml
index 4c98dba1..c568eead 100644
--- a/butterfly-cli/pom.xml
+++ b/butterfly-cli/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliApp.java b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliApp.java
index d7599822..f401c709 100644
--- a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliApp.java
+++ b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliApp.java
@@ -31,6 +31,7 @@ public class ButterflyCliApp extends ButterflyCliOption {
private static Logger logger;
+ @SuppressWarnings("PMD.DoNotCallSystemExit")
public static void main(String... arguments) throws IOException {
setButterflyHome();
setEnvironment(arguments);
@@ -59,6 +60,7 @@ private static void setButterflyHome() {
butterflyHome = new File(butterflyHomePath);
}
+ @SuppressWarnings("PMD.DoNotCallSystemExit")
private static void setEnvironment(String[] arguments) {
if(arguments.length != 0){
try {
@@ -108,6 +110,8 @@ public static File getButterflyHome() {
return butterflyHome;
}
+ // This method's visibility is intentionally being set to package
+ @SuppressWarnings("PMD.DefaultPackage")
static String getBanner() {
return banner;
}
diff --git a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliRunner.java b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliRunner.java
index d0678726..621a29fd 100644
--- a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliRunner.java
+++ b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/ButterflyCliRunner.java
@@ -57,12 +57,12 @@ public ButterflyCliRun run() throws IOException {
}
if (optionSet.has(CLI_OPTION_VERBOSE)) {
- logConfigurator.verboseMode(true);
+ logConfigurator.setVerboseMode(true);
logger.info("Verbose mode is ON");
}
if (optionSet.has(CLI_OPTION_DEBUG)) {
- logConfigurator.debugMode(true);
+ logConfigurator.setDebugMode(true);
logger.info("Debug mode is ON");
logger.info("Butterfly home: {}", ButterflyCliApp.getButterflyHome());
logger.info("JAVA_HOME: {}", System.getenv("JAVA_HOME"));
diff --git a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogConfigurator.java b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogConfigurator.java
index a47cd362..be0b93f7 100644
--- a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogConfigurator.java
+++ b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogConfigurator.java
@@ -9,7 +9,7 @@
* SLF4J implementation, but the API doesn't allow
* changing the log level in runtime, so here we
* are doing it behind the scenes.
- *
+ *
* At least we are providing this interface
* to isolate these concerns, which will make it
* easier to maintain this code if we ever replace
@@ -19,15 +19,15 @@
*/
public abstract class LogConfigurator {
- LogConfigurator() {
+ public LogConfigurator() {
setLoggerLevel("com.paypal.butterfly", Level.INFO);
}
public abstract void setLoggerLevel(String logger, Level level);
- abstract void setLoggerLevel(Class logger, Level level);
+ public abstract void setLoggerLevel(Class logger, Level level);
- public void debugMode(boolean on) {
+ public void setDebugMode(boolean on) {
if(on) {
setLoggerLevel("com.paypal.butterfly", Level.DEBUG);
} else {
@@ -35,8 +35,8 @@ public void debugMode(boolean on) {
}
}
- public abstract void verboseMode(boolean on);
+ public abstract void setVerboseMode(boolean on);
- public abstract void logToFile(boolean on);
+ public abstract void setLogToFile(boolean on);
}
diff --git a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogFileDefiner.java b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogFileDefiner.java
index 4126e522..11cab54b 100644
--- a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogFileDefiner.java
+++ b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogFileDefiner.java
@@ -49,24 +49,42 @@ public String getPropertyValue() {
}
@Override
- public void setContext(Context context) {}
+ public void setContext(Context context) {
+ // Nothing to be done here
+ }
@Override
public Context getContext() {
+ // Nothing to be done here
return null;
}
@Override
- public void addStatus(Status status) {}
+ public void addStatus(Status status) {
+ // Nothing to be done here
+ }
@Override
- public void addInfo(String s) {}
+ public void addInfo(String s) {
+ // Nothing to be done here
+ }
@Override
- public void addInfo(String s, Throwable throwable) {}
+ public void addInfo(String s, Throwable throwable) {
+ // Nothing to be done here
+ }
@Override
- public void addWarn(String s) {}
+ public void addWarn(String s) {
+ // Nothing to be done here
+ }
@Override
- public void addWarn(String s, Throwable throwable) {}
+ public void addWarn(String s, Throwable throwable) {
+ // Nothing to be done here
+ }
+
@Override
- public void addError(String s) {}
+ public void addError(String s) {
+ // Nothing to be done here
+ }
@Override
- public void addError(String s, Throwable throwable) {}
+ public void addError(String s, Throwable throwable) {
+ // Nothing to be done here
+ }
}
\ No newline at end of file
diff --git a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogbackLogConfigurator.java b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogbackLogConfigurator.java
index c493cd5e..22d10312 100644
--- a/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogbackLogConfigurator.java
+++ b/butterfly-cli/src/main/java/com/paypal/butterfly/cli/logging/LogbackLogConfigurator.java
@@ -29,7 +29,7 @@ public void setLoggerLevel(String logger, org.slf4j.event.Level level) {
}
@Override
- void setLoggerLevel(Class logger, org.slf4j.event.Level level) {
+ public void setLoggerLevel(Class logger, org.slf4j.event.Level level) {
if(level == null) {
throw new IllegalArgumentException("level argument cannot be null");
}
@@ -46,7 +46,7 @@ private Level getLogbackLogLevel(org.slf4j.event.Level slf4jLevel) {
}
@Override
- public void verboseMode(boolean on) {
+ public void setVerboseMode(boolean on) {
PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder();
patternLayoutEncoder.setPattern("[%d{HH:mm:ss.SSS}] [%highlight(%level)] %msg%n");
patternLayoutEncoder.setContext(loggerContext);
@@ -62,7 +62,7 @@ public void verboseMode(boolean on) {
}
@Override
- public void logToFile(boolean on) {
+ public void setLogToFile(boolean on) {
loggerContext.getLogger("ROOT").detachAppender("FILE");
}
diff --git a/butterfly-cli/src/test/java/com/paypal/butterfly/cli/ButterflyCliTest.java b/butterfly-cli/src/test/java/com/paypal/butterfly/cli/ButterflyCliTest.java
index c68abd48..9bf77a97 100644
--- a/butterfly-cli/src/test/java/com/paypal/butterfly/cli/ButterflyCliTest.java
+++ b/butterfly-cli/src/test/java/com/paypal/butterfly/cli/ButterflyCliTest.java
@@ -1,16 +1,15 @@
package com.paypal.butterfly.cli;
-import com.test.SampleExtension;
-import com.test.SampleTransformationTemplate;
import com.paypal.butterfly.cli.logging.LogConfigurator;
import com.paypal.butterfly.extensions.api.exception.ButterflyException;
import com.paypal.butterfly.extensions.api.upgrade.UpgradePath;
import com.paypal.butterfly.facade.ButterflyFacade;
import com.paypal.butterfly.facade.Configuration;
import com.paypal.butterfly.facade.TransformationResult;
+import com.test.SampleExtension;
+import com.test.SampleTransformationTemplate;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -34,6 +33,10 @@ public class ButterflyCliTest extends PowerMockTestCase {
@Mock
private ButterflyFacade facade;
+ // Even though this variable is not used explicitly in this class,
+ // it is necessary to its proper execution, since the mock initialization
+ // is happening regardless of it
+ @SuppressWarnings("PMD.UnusedPrivateField")
@Mock
private LogConfigurator logConfigurator;
@@ -41,18 +44,18 @@ public class ButterflyCliTest extends PowerMockTestCase {
@BeforeMethod
public void beforeTest() throws ButterflyException {
- TransformationResult mockResult = Mockito.mock(TransformationResult.class);
+ TransformationResult mockResult = mock(TransformationResult.class);
- Mockito.when(facade.transform(Mockito.any(File.class), Mockito.any(String.class))).thenReturn(mockResult);
- Mockito.when(facade.transform(Mockito.any(File.class), Mockito.any(String.class), Mockito.any(Configuration.class))).thenReturn(mockResult);
- Mockito.when(facade.transform(Mockito.any(File.class), Mockito.any(Class.class))).thenReturn(mockResult);
- Mockito.when(facade.transform(Mockito.any(File.class), Mockito.any(Class.class), Mockito.any(Configuration.class))).thenReturn(mockResult);
- Mockito.when(facade.transform(Mockito.any(File.class), Mockito.any(UpgradePath.class))).thenReturn(mockResult);
- Mockito.when(facade.transform(Mockito.any(File.class), Mockito.any(UpgradePath.class), Mockito.any(Configuration.class))).thenReturn(mockResult);
+ when(facade.transform(any(File.class), any(String.class))).thenReturn(mockResult);
+ when(facade.transform(any(File.class), any(String.class), any(Configuration.class))).thenReturn(mockResult);
+ when(facade.transform(any(File.class), any(Class.class))).thenReturn(mockResult);
+ when(facade.transform(any(File.class), any(Class.class), any(Configuration.class))).thenReturn(mockResult);
+ when(facade.transform(any(File.class), any(UpgradePath.class))).thenReturn(mockResult);
+ when(facade.transform(any(File.class), any(UpgradePath.class), any(Configuration.class))).thenReturn(mockResult);
File file = new File("");
- Mockito.when(mockResult.getTransformedApplicationLocation()).thenReturn(file);
- Mockito.when(mockResult.getManualInstructionsFile()).thenReturn(file);
+ when(mockResult.getTransformedApplicationLocation()).thenReturn(file);
+ when(mockResult.getManualInstructionsFile()).thenReturn(file);
sampleAppFolder = new File(this.getClass().getResource("/sample_app").getFile());
}
@@ -69,7 +72,7 @@ public void testListingExtensions() throws IOException {
String[] arguments = {"-l", "-v"};
butterflyCli.setOptionSet(arguments);
-
+
int status = butterflyCli.run().getExitStatus();
Assert.assertEquals(status, 0);
@@ -100,7 +103,7 @@ public void testTransformation() throws IOException, ButterflyException {
*/
@Test
public void testTransformationWithShortcut() throws IOException, ButterflyException {
- Mockito.when(facade.getRegisteredExtension()).thenReturn(new SampleExtension());
+ when(facade.getRegisteredExtension()).thenReturn(new SampleExtension());
String arguments[] = {sampleAppFolder.getAbsolutePath(), "-s", "2"};
butterflyCli.setOptionSet(arguments);
@@ -119,7 +122,7 @@ public void testTransformationWithShortcut() throws IOException, ButterflyExcept
*/
@Test
public void testTransformationWithShortcutButIgnoringIt() throws IOException, ButterflyException {
- Mockito.when(facade.getRegisteredExtension()).thenReturn(new SampleExtension());
+ when(facade.getRegisteredExtension()).thenReturn(new SampleExtension());
String arguments[] = {sampleAppFolder.getAbsolutePath(), "-t", "com.test.SampleTransformationTemplate", "-z", "-s", "2"};
butterflyCli.setOptionSet(arguments);
@@ -173,7 +176,7 @@ public void testTransformationWithValidOutPutDir() throws IOException, Butterfly
@Test
public void testAutomaticResolution() throws IOException, ButterflyException {
- Mockito.doReturn(SampleTransformationTemplate.class).when(facade).automaticResolution(Mockito.any(File.class));
+ doReturn(SampleTransformationTemplate.class).when(facade).automaticResolution(any(File.class));
String arguments[] = {sampleAppFolder.getAbsolutePath()};
butterflyCli.setOptionSet(arguments);
int status = butterflyCli.run().getExitStatus();
diff --git a/butterfly-cli/src/test/java/com/paypal/butterfly/cli/logging/LogbackLogConfiguratorTest.java b/butterfly-cli/src/test/java/com/paypal/butterfly/cli/logging/LogbackLogConfiguratorTest.java
index 3448c9ca..ac849140 100644
--- a/butterfly-cli/src/test/java/com/paypal/butterfly/cli/logging/LogbackLogConfiguratorTest.java
+++ b/butterfly-cli/src/test/java/com/paypal/butterfly/cli/logging/LogbackLogConfiguratorTest.java
@@ -26,7 +26,7 @@ public class LogbackLogConfiguratorTest extends PowerMockTestCase {
public void testVerboseOn() {
Assert.assertNotNull(logbackVerboseConfigurator);
Assert.assertNotNull(loggerContext);
- logbackVerboseConfigurator.debugMode(true);
+ logbackVerboseConfigurator.setDebugMode(true);
Assert.assertTrue(loggerContext.getLogger("com.paypal.butterfly").getLevel() == ch.qos.logback.classic.Level.DEBUG);
}
@@ -35,7 +35,7 @@ public void testVerboseOn() {
public void testVerboseOff() {
Assert.assertNotNull(logbackVerboseConfigurator);
Assert.assertNotNull(loggerContext);
- logbackVerboseConfigurator.debugMode(false);
+ logbackVerboseConfigurator.setDebugMode(false);
Assert.assertTrue(loggerContext.getLogger("com.paypal.butterfly").getLevel() == ch.qos.logback.classic.Level.INFO);
}
diff --git a/butterfly-core/pom.xml b/butterfly-core/pom.xml
index 60d9146d..f9689133 100644
--- a/butterfly-core/pom.xml
+++ b/butterfly-core/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/InternalTransformationException.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/InternalTransformationException.java
index 2132454b..afb7c723 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/InternalTransformationException.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/InternalTransformationException.java
@@ -11,7 +11,7 @@
*/
class InternalTransformationException extends TransformationException {
- TransformationContextImpl transformationContext;
+ private TransformationContextImpl transformationContext;
InternalTransformationException(String exceptionMessage, TransformationContextImpl transformationContext) {
super(exceptionMessage);
@@ -27,6 +27,8 @@ class InternalTransformationException extends TransformationException {
this(e.getMessage(), e, transformationContext);
}
+ // This method's visibility is intentionally being set to package
+ @SuppressWarnings("PMD.DefaultPackage")
TransformationContextImpl getTransformationContext() {
return transformationContext;
}
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/MdFileManualInstructionsHandler.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/MdFileManualInstructionsHandler.java
index 345d850b..bdf78f28 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/MdFileManualInstructionsHandler.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/MdFileManualInstructionsHandler.java
@@ -17,7 +17,7 @@
/**
* This class processes all {@link com.paypal.butterfly.extensions.api.utilities.ManualInstruction}
- * objects present in a {@link TransformationContextImpl] object and persist them in a set of MD files,
+ * objects present in a {@link TransformationContextImpl} object and persist them in a set of MD files,
* to be placed in the transformed application folder
*
* @author facarvalho
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/TemplateTransformation.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/TemplateTransformation.java
index d89b928d..bfeb8e82 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/TemplateTransformation.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/TemplateTransformation.java
@@ -9,6 +9,7 @@
*
* @author facarvalho
*/
+@SuppressWarnings("PMD.DefaultPackage")
public class TemplateTransformation extends Transformation {
private static final String TO_STRING_SYNTAX = "{ \"application\" : %s, \"template\" : %s, \"templateClass\" : %s }";
@@ -39,7 +40,7 @@ String getExtensionVersion() {
}
@Override
- String getTemplatetName() {
+ String getTemplateName() {
return template.getName();
}
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/Transformation.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/Transformation.java
index 02efd4da..ebf2568f 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/Transformation.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/Transformation.java
@@ -13,6 +13,7 @@
*
* @author facarvalho
*/
+@SuppressWarnings("PMD.DefaultPackage")
public abstract class Transformation {
private static final Logger logger = LoggerFactory.getLogger(Transformation.class);
@@ -73,7 +74,7 @@ File getManualInstructionsDir() {
abstract String getExtensionVersion();
- abstract String getTemplatetName();
+ abstract String getTemplateName();
protected String getExtensionName(Class extends Extension> extension) {
return extension.getName();
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationContextImpl.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationContextImpl.java
index fc95030e..ce37dc05 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationContextImpl.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationContextImpl.java
@@ -18,6 +18,7 @@
*
* @author facarvalho
*/
+@SuppressWarnings("PMD.DefaultPackage")
@SuppressFBWarnings("URF_UNREAD_FIELD")
class TransformationContextImpl implements TransformationContext {
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationEngine.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationEngine.java
index 2603edef..90f1f198 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationEngine.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationEngine.java
@@ -11,7 +11,6 @@
import com.paypal.butterfly.facade.TransformationResult;
import com.paypal.butterfly.facade.exception.TransformationException;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -56,6 +55,7 @@ public void setupListeners() {
*
* @param transformation the transformation object
* @throws TransformationException if the transformation is aborted for any reason
+ * @return the result after performing this transformation
*/
public TransformationResult perform(Transformation transformation) throws TransformationException {
if(logger.isDebugEnabled()) {
@@ -63,7 +63,7 @@ public TransformationResult perform(Transformation transformation) throws Transf
}
logger.info("Extension name:\t\t\t\t\t{}", transformation.getExtensionName());
logger.info("Extension version:\t\t\t\t{}", transformation.getExtensionVersion());
- logger.info("Transformation template:\t\t\t{}", transformation.getTemplatetName());
+ logger.info("Transformation template:\t\t\t{}", transformation.getTemplateName());
File transformedAppFolder = prepareOutputFolder(transformation);
List transformationContexts = new ArrayList<>();
@@ -463,7 +463,7 @@ private void processUtilityExecutionResult(TransformationUtility utility, Perfor
}
break;
case VALUE:
- logger.debug("\t-\t - [{}][Result: {}][Utility: {}]", StringUtils.abbreviate(utility.toString(), 240), StringUtils.abbreviate(executionResult.getValue().toString(), 120), utility.getName());
+ logger.debug("\t-\t - [{}][Result: {}][Utility: {}]", utility.toString(), executionResult.getValue().toString(), utility.getName());
break;
case WARNING:
processExecutionResultWarningType(utility, executionResult, "-");
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationStatisticsImpl.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationStatisticsImpl.java
index 0d19b5b5..9a40fc0d 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationStatisticsImpl.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/TransformationStatisticsImpl.java
@@ -2,14 +2,19 @@
import com.paypal.butterfly.extensions.api.*;
import com.paypal.butterfly.extensions.api.metrics.TransformationStatistics;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* POJO to hold transformation statistics
*
* @author facarvalho
*/
+@SuppressWarnings("PMD.DefaultPackage")
class TransformationStatisticsImpl implements TransformationStatistics {
+ private static Logger logger = LoggerFactory.getLogger(TransformationStatisticsImpl.class);
+
// Number of utilities performed
private int utilitiesCount = 0;
@@ -43,6 +48,9 @@ void registerResult(PerformResult result) {
case SKIPPED_DEPENDENCY:
performResults.skippedDependencyCount++;
break;
+ default:
+ logger.error("Unknown result type {}", result.getType());
+ break;
}
TransformationUtility source = result.getSource();
@@ -64,6 +72,9 @@ void registerResult(PerformResult result) {
case ERROR:
executionResults.operations.errorCount++;
break;
+ default:
+ logger.error("Unknown result type {}", result.getType());
+ break;
}
}
} else {
@@ -83,6 +94,9 @@ void registerResult(PerformResult result) {
case ERROR:
executionResults.utilities.errorCount++;
break;
+ default:
+ logger.error("Unknown result type {}", result.getType());
+ break;
}
}
}
diff --git a/butterfly-core/src/main/java/com/paypal/butterfly/core/UpgradePathTransformation.java b/butterfly-core/src/main/java/com/paypal/butterfly/core/UpgradePathTransformation.java
index 0faf2e21..7d87bbdf 100644
--- a/butterfly-core/src/main/java/com/paypal/butterfly/core/UpgradePathTransformation.java
+++ b/butterfly-core/src/main/java/com/paypal/butterfly/core/UpgradePathTransformation.java
@@ -10,6 +10,7 @@
*
* @author facarvalho
*/
+@SuppressWarnings("PMD.DefaultPackage")
public class UpgradePathTransformation extends Transformation {
private static final String TO_STRING_SYNTAX = "{ \"application\" : %s, \"upgrade from version\" : %s, \"to version\" : %s }";
@@ -40,7 +41,7 @@ String getExtensionVersion() {
}
@Override
- String getTemplatetName() {
+ String getTemplateName() {
return upgradePath.getFirstStepTemplateName();
}
diff --git a/butterfly-core/src/test/java/com/paypal/butterfly/core/ButteflyFacadeImplTest.java b/butterfly-core/src/test/java/com/paypal/butterfly/core/ButteflyFacadeImplTest.java
index 62785d73..ddff6f23 100644
--- a/butterfly-core/src/test/java/com/paypal/butterfly/core/ButteflyFacadeImplTest.java
+++ b/butterfly-core/src/test/java/com/paypal/butterfly/core/ButteflyFacadeImplTest.java
@@ -6,9 +6,8 @@
import com.paypal.butterfly.core.sample.SampleUpgradeStep;
import com.paypal.butterfly.extensions.api.Extension;
import com.paypal.butterfly.extensions.api.exception.ButterflyException;
-import com.paypal.butterfly.extensions.api.upgrade.UpgradePath;
-import com.paypal.butterfly.facade.Configuration;
import com.paypal.butterfly.extensions.api.exception.TemplateResolutionException;
+import com.paypal.butterfly.extensions.api.upgrade.UpgradePath;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.modules.testng.PowerMockTestCase;
@@ -16,7 +15,6 @@
import org.testng.annotations.Test;
import java.io.File;
-import java.util.List;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.times;
@@ -25,7 +23,7 @@
/**
* ButteflyFacadeImplTest
- *
+ *
* Created by vkuncham on 11/7/2016.
*/
public class ButteflyFacadeImplTest extends PowerMockTestCase {
@@ -53,76 +51,66 @@ public void testGetRegisteredExtension() {
@Test(expectedExceptions = TemplateResolutionException.class, expectedExceptionsMessageRegExp = "No transformation template applies")
public void testAutomaticResolutionNoTemplate() throws TemplateResolutionException {
- when(extensionRegistry.getExtension()).thenReturn(extensionRegistry_test.getExtension());
- Assert.assertEquals(butterflyFacadeImpl.automaticResolution(new File("testTransformation1")),null);
+ when(extensionRegistry.getExtension()).thenReturn(extensionRegistry_test.getExtension());
+ Assert.assertEquals(butterflyFacadeImpl.automaticResolution(new File("testTransformation1")), null);
}
@Test
public void testAutomaticResolutionTemplate() throws TemplateResolutionException {
when(extensionRegistry.getExtension()).thenReturn(extensionRegistry_test.getExtension());
- Assert.assertEquals(butterflyFacadeImpl.automaticResolution(applicationFolder),SampleTransformationTemplate.class);
+ Assert.assertEquals(butterflyFacadeImpl.automaticResolution(applicationFolder), SampleTransformationTemplate.class);
}
- @Test(expectedExceptions = IllegalArgumentException.class,
- expectedExceptionsMessageRegExp = "Template class name cannot be blank")
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Template class name cannot be blank")
public void testTransformWithTemplateClassAsEmptyString() throws ButterflyException {
- butterflyFacadeImpl.transform(applicationFolder,"");
+ butterflyFacadeImpl.transform(applicationFolder, "");
}
- @Test(expectedExceptions = IllegalArgumentException.class,
- expectedExceptionsMessageRegExp = "Template class name cannot be blank")
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Template class name cannot be blank")
public void testTransformWithTemplateAsNull() throws ButterflyException {
- butterflyFacadeImpl.transform(applicationFolder,(String) null);
+ butterflyFacadeImpl.transform(applicationFolder, (String) null);
}
- @Test(expectedExceptions = InternalException.class,
- expectedExceptionsMessageRegExp = "Template class TestTemplate not found.*")
+ @Test(expectedExceptions = InternalException.class, expectedExceptionsMessageRegExp = "Template class TestTemplate not found.*")
public void testTransformWithInValidTemplate() throws ButterflyException {
- butterflyFacadeImpl.transform(applicationFolder,"TestTemplate");
+ butterflyFacadeImpl.transform(applicationFolder, "TestTemplate");
}
@Test
public void testTransformWithValidTemplate() throws ButterflyException {
-
- TemplateTransformation templateTransformation = new TemplateTransformation(new Application(applicationFolder),
- new SampleTransformationTemplate(),new Configuration());
butterflyFacadeImpl.transform(applicationFolder, "com.paypal.butterfly.core.sample.SampleTransformationTemplate");
- verify(transformationEngine,times(1)).perform((TemplateTransformation) anyObject());
+ verify(transformationEngine, times(1)).perform((TemplateTransformation) anyObject());
}
- @Test(expectedExceptions = InternalException.class,
- expectedExceptionsMessageRegExp = "Template class class com.paypal.butterfly.core.sample." +
- "SampleAbstractTransformationTemplate could not be instantiated.*")
+ @Test(expectedExceptions = InternalException.class, expectedExceptionsMessageRegExp = "Template class class com.paypal.butterfly.core.sample.SampleAbstractTransformationTemplate could not be instantiated.*")
public void testTransformWithAbstractTemplate() throws ButterflyException {
- butterflyFacadeImpl.transform(applicationFolder,"com.paypal.butterfly.core.sample.SampleAbstractTransformationTemplate");
+ butterflyFacadeImpl.transform(applicationFolder, "com.paypal.butterfly.core.sample.SampleAbstractTransformationTemplate");
}
@Test
public void testTransformWithValidTemplateAsClass() throws ButterflyException {
- butterflyFacadeImpl.transform(applicationFolder,SampleTransformationTemplate.class);
- verify(transformationEngine,times(1)).perform((TemplateTransformation) anyObject());
+ butterflyFacadeImpl.transform(applicationFolder, SampleTransformationTemplate.class);
+ verify(transformationEngine, times(1)).perform((TemplateTransformation) anyObject());
}
- @Test(expectedExceptions = IllegalArgumentException.class,
- expectedExceptionsMessageRegExp ="Invalid application folder testTransformation1"
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Invalid application folder testTransformation1"
)
public void testTransformWithValidUpgradePathInvalidAppFolder() throws ButterflyException {
- UpgradePath upgradePath = new UpgradePath(SampleUpgradeStep.class);
- butterflyFacadeImpl.transform(new File("testTransformation1"),upgradePath);
+ UpgradePath upgradePath = new UpgradePath(SampleUpgradeStep.class);
+ butterflyFacadeImpl.transform(new File("testTransformation1"), upgradePath);
}
- @Test(expectedExceptions = IllegalArgumentException.class,
- expectedExceptionsMessageRegExp ="Upgrade path cannot be null"
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Upgrade path cannot be null"
)
public void testTransformWithInValidUpgradePath() throws ButterflyException {
- butterflyFacadeImpl.transform(applicationFolder, (UpgradePath) null);
+ butterflyFacadeImpl.transform(applicationFolder, (UpgradePath) null);
}
@Test
public void testTransformWithValidUpgradePath() throws ButterflyException {
- UpgradePath upgradePath = new UpgradePath(SampleUpgradeStep.class);
- butterflyFacadeImpl.transform(applicationFolder,upgradePath);
- verify(transformationEngine,times(1)).perform((UpgradePathTransformation)anyObject());
+ UpgradePath upgradePath = new UpgradePath(SampleUpgradeStep.class);
+ butterflyFacadeImpl.transform(applicationFolder, upgradePath);
+ verify(transformationEngine, times(1)).perform((UpgradePathTransformation) anyObject());
}
}
diff --git a/butterfly-extensions-api/pom.xml b/butterfly-extensions-api/pom.xml
index eeb22aa6..e7169198 100644
--- a/butterfly-extensions-api/pom.xml
+++ b/butterfly-extensions-api/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ContextAttributeRetriever.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ContextAttributeRetriever.java
index e508d523..e77228ae 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ContextAttributeRetriever.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ContextAttributeRetriever.java
@@ -18,12 +18,12 @@
*
* @author facarvalho
*/
-public class ContextAttributeRetriever extends TransformationUtility {
+public class ContextAttributeRetriever extends TransformationUtility {
private static final String DESCRIPTION = "Retrieves value of transformation context attribute '%s'";
private String attributeName;
- private VT attributeValue;
+ private T attributeValue;
private boolean executed = false;
public ContextAttributeRetriever() {
@@ -49,7 +49,7 @@ public String getDescription() {
protected ExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
executed = true;
try {
- attributeValue = (VT) transformationContext.get(attributeName);
+ attributeValue = (T) transformationContext.get(attributeName);
return TUExecutionResult.nullResult(this);
} catch (IllegalArgumentException | ClassCastException ex) {
return TUExecutionResult.error(this, ex);
@@ -64,7 +64,7 @@ protected ExecutionResult execution(File transformedAppFolder, TransformationCon
*
* @return the value of the transformation context attribute specified earlier
*/
- public VT getAttributeValue() {
+ public T getAttributeValue() {
if (!executed) {
throw new IllegalStateException(getName() + " has not had a chance to be executed yet");
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/DoubleCondition.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/DoubleCondition.java
index e407779c..37eb91c0 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/DoubleCondition.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/DoubleCondition.java
@@ -14,18 +14,28 @@
* for example). For conditions
* based on evaluating a single file see {@link SingleCondition}.
* For conditions based on multiple files see {@link MultipleConditions}
+ *
+ * Important: it returns true if both files don't exist,
+ * and it returns false if only one of them exists.
*
+ * @author facarvalho
* @see SingleCondition
* @see MultipleConditions
- *
- * @author facarvalho
*/
-public abstract class DoubleCondition extends UtilityCondition {
+public abstract class DoubleCondition extends UtilityCondition {
// The name of the transformation context attribute
// that refers to the file to be compared against the baseline file
private String attribute;
+ // TODO
+ // Rename attribute to compareAttribute
+
+ // TODO
+ // Add a new instance variable called compareRelative, to be used as an alternative to compareAttribute,
+ // pointing directly to the comparison file, relative to the transformed application folder,
+ // and without the need for a transformation context attribute.
+
/**
* Condition to determine if a transformation utility
* should be executed or not. Every
@@ -34,23 +44,22 @@ public abstract class DoubleCondition extends Utili
* is based on two files (when comparing if two XML files are equal
* for example)
*/
- public DoubleCondition() {
+ public DoubleCondition() {
}
/**
- * Set the name of the transformation context attribute
- * that refers to the file to be compared against the
- * baseline file, which is set by regular {@link com.paypal.butterfly.extensions.api.TransformationUtility}
- * methods, like {@link #relative(String)} or {@link #absolute(String)}
+ * Condition to determine if a transformation utility
+ * should be executed or not. Every
+ * DoubleUtilityCondition subclass result type must always
+ * be boolean. The criteria to this type of condition
+ * is based on two files (when comparing if two XML files are equal
+ * for example)
*
* @param attribute the name of the transformation context attribute
* that refers to the file to be compared against the baseline file
- * @return this utility condition instance
*/
- public DUC setAttribute(String attribute) {
- checkForBlankString("attribute", attribute);
- this.attribute = attribute;
- return (DUC) this;
+ public DoubleCondition(String attribute) {
+ setAttribute(attribute);
}
/**
@@ -66,13 +75,34 @@ public String getAttribute() {
return attribute;
}
+ /**
+ * Set the name of the transformation context attribute
+ * that refers to the file to be compared against the
+ * baseline file, which is set by regular {@link com.paypal.butterfly.extensions.api.TransformationUtility}
+ * methods, like {@link #relative(String)} or {@link #absolute(String)}
+ *
+ * @param attribute the name of the transformation context attribute
+ * that refers to the file to be compared against the baseline file
+ * @return this utility condition instance
+ */
+ public T setAttribute(String attribute) {
+ checkForBlankString("attribute", attribute);
+ this.attribute = attribute;
+ return (T) this;
+ }
+
@Override
- protected ExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
+ protected TUExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
try {
File baselineFile = getAbsoluteFile(transformedAppFolder, transformationContext);
File comparisonFile = getComparisonFile(transformationContext);
- boolean result = compare(baselineFile, comparisonFile);
+ boolean result = false;
+ if (baselineFile.exists() && comparisonFile.exists()) {
+ result = compare(baselineFile, comparisonFile);
+ } else if (!baselineFile.exists() && !comparisonFile.exists()) {
+ result = true;
+ }
return TUExecutionResult.value(this, result);
} catch (TransformationUtilityException e) {
@@ -84,7 +114,7 @@ protected ExecutionResult execution(File transformedAppFolder, TransformationCon
* Returns true only if the compared files meet the comparison
* criteria established and implemented by the subclass
*
- * @param baselineFile the baseline file used for comparison
+ * @param baselineFile the baseline file used for comparison
* @param comparisonFile the file to be compared against the baseline file
* @return this utility condition instance
*/
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ExecutionResult.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ExecutionResult.java
index 7f420ac9..a4ff5c37 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ExecutionResult.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/ExecutionResult.java
@@ -10,7 +10,7 @@
*
* @author facarvalho
*/
-public abstract class ExecutionResult extends Result {
+public abstract class ExecutionResult extends Result {
ExecutionResult(S source) {
super(source);
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/FilterFiles.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/FilterFiles.java
index 33480251..6fcf4ca4 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/FilterFiles.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/FilterFiles.java
@@ -150,19 +150,14 @@ protected TUExecutionResult execution(File transformedAppFolder, TransformationC
* @return this transformation utility instance
*/
public SingleCondition newConditionInstance(File transformedAppFolder, File file) {
- try {
- SingleCondition condition = (SingleCondition) conditionTemplate.copy();
- condition.relative(TransformationUtility.getRelativePath(transformedAppFolder, file));
- condition.setSaveResult(false);
-
- conditionInstanceCounter++;
- condition.setName(String.format("%s-%d", conditionTemplate.getName(), conditionInstanceCounter));
-
- return condition;
- } catch (CloneNotSupportedException e) {
- String exceptionMessage = String.format("Error when preparing single condition instance for %s", getName());
- throw new TransformationUtilityException(exceptionMessage, e);
- }
+ SingleCondition condition = (SingleCondition) conditionTemplate.copy();
+ condition.relative(TransformationUtility.getRelativePath(transformedAppFolder, file));
+ condition.setSaveResult(false);
+
+ conditionInstanceCounter++;
+ condition.setName(String.format("%s-%d", conditionTemplate.getName(), conditionInstanceCounter));
+
+ return condition;
}
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleConditions.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleConditions.java
index c0fa59ec..36d07a75 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleConditions.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleConditions.java
@@ -211,19 +211,14 @@ protected TUExecutionResult execution(File transformedAppFolder, TransformationC
* @return the new utility condition created based on this instance
*/
public UtilityCondition newConditionInstance(File transformedAppFolder, File file) {
- try {
- UtilityCondition condition = (UtilityCondition) conditionTemplate.copy();
- condition.relative(TransformationUtility.getRelativePath(transformedAppFolder, file));
- condition.setSaveResult(false);
-
- conditionInstanceCounter++;
- condition.setName(String.format("%s-%d", conditionTemplate.getName(), conditionInstanceCounter));
-
- return condition;
- } catch (CloneNotSupportedException e) {
- String exceptionMessage = String.format("Error when preparing condition instance for %s", getName());
- throw new TransformationUtilityException(exceptionMessage, e);
- }
+ UtilityCondition condition = (UtilityCondition) conditionTemplate.copy();
+ condition.relative(TransformationUtility.getRelativePath(transformedAppFolder, file));
+ condition.setSaveResult(false);
+
+ conditionInstanceCounter++;
+ condition.setName(String.format("%s-%d", conditionTemplate.getName(), conditionInstanceCounter));
+
+ return condition;
}
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleOperations.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleOperations.java
index 9570e0be..c5de1d25 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleOperations.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/MultipleOperations.java
@@ -320,6 +320,9 @@ private TransformationOperation createClone(int order, File transformedAppFolder
@Override
public List getChildren() {
+ if (operations == null) {
+ return Collections.emptyList();
+ }
return Collections.unmodifiableList(operations);
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/Result.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/Result.java
index 94b784b4..c47fa91b 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/Result.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/Result.java
@@ -9,7 +9,7 @@
*
* @author facarvalho
*/
-abstract class Result {
+abstract class Result {
// The source of this result, which could be for example
// a transformation utility instance or a transformation
@@ -38,25 +38,25 @@ abstract class Result {
setType(type);
}
- private RT setSource(S source) {
+ private R setSource(S source) {
if(source == null) {
throw new IllegalArgumentException("Result source cannot be null");
}
this.source = source;
- return (RT) this;
+ return (R) this;
}
- protected RT setType(T type) {
+ protected R setType(T type) {
if(type == null) {
throw new IllegalArgumentException("Result type cannot be null");
}
this.type = type;
- return (RT) this;
+ return (R) this;
}
- public RT setDetails(String details) {
+ public R setDetails(String details) {
this.details = details;
- return (RT) this;
+ return (R) this;
}
/**
@@ -68,7 +68,7 @@ public RT setDetails(String details) {
* @param exception associated with the execution result
* @return this object
*/
- protected RT setException(Exception exception) {
+ protected R setException(Exception exception) {
if(exception == null) {
throw new IllegalArgumentException("Exception object cannot be null");
}
@@ -76,7 +76,7 @@ protected RT setException(Exception exception) {
throw new IllegalArgumentException("Exception cannot be assigned to " + type);
}
this.exception = exception;
- return (RT) this;
+ return (R) this;
}
/**
@@ -87,10 +87,10 @@ protected RT setException(Exception exception) {
* @param warning the warning to be added
* @return this object
*/
- public RT addWarning(Exception warning) {
+ public R addWarning(Exception warning) {
warnings.add(warning);
changeTypeOnWarning();
- return (RT) this;
+ return (R) this;
}
/**
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/SingleCondition.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/SingleCondition.java
index d8da65cc..6ba9bd6b 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/SingleCondition.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/SingleCondition.java
@@ -16,5 +16,5 @@
*
* @author facarvalho
*/
-public abstract class SingleCondition extends UtilityCondition {
+public abstract class SingleCondition extends UtilityCondition {
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationOperation.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationOperation.java
index 6853a8e1..b8c339bf 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationOperation.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationOperation.java
@@ -1,6 +1,12 @@
package com.paypal.butterfly.extensions.api;
+import com.paypal.butterfly.extensions.api.exception.TransformationUtilityException;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+
/**
* Special type of {@link TransformationUtility} that applies a modification to the project.
*
@@ -17,17 +23,17 @@
* The default value for {@link #relative(String)} is {@code null}, which means
* it must be set explicitly, unless an absolute path is set via {@link #absolute(String)}
* or {@link #absolute(String, String)}
- *
- * Every transformation operation subclass must override {@link #clone()} and every operation
- * specific property defined in the operation subclass must be copied from the original
- * object to the clone object. Properties inherited from this class and its super classes
- * MUST NOT be copied from original object to cloned object, since that is all already taken
- * care of properly by the framework. Notice that name, parent and path (absolute and relative)
- * are NECESSARILY NOT assigned to the clone object
*
* @author facarvalho
*/
-public abstract class TransformationOperation extends TransformationUtility {
+public abstract class TransformationOperation extends TransformationUtility {
+
+ // An optional temporary read-only copy of the file to be modified
+ // This file gets automatically deleted after the transformation operation execution
+ private File readFile;
+
+ // A prefix used to name the temporary read-only file
+ private static final String READ_FILE_PREFIX = "butterfly_";
public TransformationOperation() {
// Different than regular Transformation Utilities, the default value here is null, which means
@@ -36,8 +42,52 @@ public TransformationOperation() {
}
@Override
- protected final TO setSaveResult(boolean saveResult) {
+ protected final T setSaveResult(boolean saveResult) {
throw new UnsupportedOperationException("Transformation operations must always save results");
}
+ /**
+ * Creates and returns a temporary read-only copy of the file to be modified.
+ *
+ * The file to be modified by any transformation operation is set via
+ * {@link #relative(String)}, {@link #absolute(String)} or {@link #absolute(String, String)}).
+ * Some transformation operations though might need to read the file to be modified
+ * as a stream, and modify it by writing to an output stream as that same file
+ * is read. Since it is impossible to modify a file at the same time it is being read,
+ * this utility method offers an convenient way to create a temporary read-only
+ * copy of the file to be modified. This copy should be used to be read, while the original
+ * file can be modified.
+ *
+ * Important notes:
+ *
+ *
At the first time this method is called, the temporary file will be created and returned. If called again, the same temporary file created at the first time will be returned.
+ *
The read-only file will not reflect the changes performed in the original file at any moment, always keeping its original state.
+ *
There is no need to delete the temporary file after using it. Butterfly automatically deletes it when the JVM terminates.
+ *
+ *
+ * @param transformedAppFolder the folder where the transformed application code is
+ * @param transformationContext the transformation context object
+ * @return a temporary read-only copy of the file to be modified
+ * @throws IOException if the temporary file could not be created
+ */
+ protected final File getOrCreateReadFile(File transformedAppFolder, TransformationContext transformationContext) throws IOException {
+ if (readFile == null) {
+ File originalFile = getAbsoluteFile(transformedAppFolder, transformationContext);
+ readFile = File.createTempFile(READ_FILE_PREFIX, null);
+ FileUtils.copyFile(originalFile, readFile);
+ readFile.setReadOnly();
+ }
+
+ return readFile;
+ }
+
+ @Override
+ public PerformResult perform(File transformedAppFolder, TransformationContext transformationContext) throws TransformationUtilityException {
+ PerformResult performResult = super.perform(transformedAppFolder, transformationContext);
+ if (readFile != null) {
+ readFile.deleteOnExit();
+ }
+
+ return performResult;
+ }
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationTemplate.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationTemplate.java
index 0fb9688c..5bc702f6 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationTemplate.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationTemplate.java
@@ -170,9 +170,20 @@ public final String loop(TransformationUtility utility, UtilityCondition conditi
return add(new TransformationUtilityLoop(utility).setCondition(condition));
}
+ @Deprecated
@Override
public final void log(String logMessage) {
- add(new Log().setLogMessage(logMessage));
+ info(logMessage);
+ }
+
+ @Override
+ public final void info(String infoMessage) {
+ add(new Log().setLogMessage(infoMessage));
+ }
+
+ @Override
+ public final void debug(String debugMessage) {
+ add(new Log().setLogMessage(debugMessage).setLogLevel(Level.DEBUG));
}
@Override
@@ -180,9 +191,20 @@ public final void log(Level logLevel, String logMessage) {
add(new Log().setLogLevel(logLevel).setLogMessage(logMessage));
}
+ @Deprecated
@Override
public final void log(String logMessage, String... attributeNames) {
- add(new Log().setLogMessage(logMessage).setAttributeNames(attributeNames));
+ info(logMessage, attributeNames);
+ }
+
+ @Override
+ public final void info(String infoMessage, String... attributeNames) {
+ add(new Log().setLogMessage(infoMessage).setAttributeNames(attributeNames));
+ }
+
+ @Override
+ public final void debug(String debugMessage, String... attributeNames) {
+ add(new Log().setLogMessage(debugMessage).setAttributeNames(attributeNames).setLogLevel(Level.DEBUG));
}
@Override
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtility.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtility.java
index 0d95de5d..934b6f9c 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtility.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtility.java
@@ -35,20 +35,13 @@
* Every TransformationUtility subclass MUST have a public no arguments default constructor,
* and also public setters and getters for all properties they want to expose via {@link #set(String, String)}.
* In addition to that, every setter must return the TransformationUtility instance.
- *
- * Also, every TransformationUtility subclass must override {@link #clone()} and every utility
- * specific property defined in the subclass must be copied from the original
- * object to the clone object. Properties inherited from this class and its super classes
- * MUST NOT be copied from original object to cloned object, since that is all already taken
- * care of properly by the framework. Notice that name, parent and path (absolute and relative)
- * are NECESSARILY NOT assigned to the clone object
*
* @author facarvalho
*/
// TODO create another type to be parent of TO and TU, this way the result type will be better organized
// How to name it? transformation node?
// This type should be the one to be added to a template
-public abstract class TransformationUtility implements Cloneable {
+public abstract class TransformationUtility implements Cloneable {
private static final Logger logger = LoggerFactory.getLogger(TransformationUtility.class);
@@ -59,10 +52,6 @@ public abstract class TransformationUtility im
// 1 means first
private int order = -1;
- public int getOrder() {
- return order;
- }
-
// The parent this utility instance has been registered to
private TransformationUtilityParent parent;
@@ -98,12 +87,12 @@ public int getOrder() {
// Map of properties to be set later, during transformation time.
// The keys must be utility Java property names, and the values
// must be transformation context attribute names
- private Map latePropertiesAttributes = new HashMap();
+ private Map latePropertiesAttributes = new HashMap<>();
// Map of properties to be set later, during transformation time.
// The keys must be utility Java property names, and the values
// must be the setter methods
- private Map latePropertiesSetters = new HashMap();
+ private Map latePropertiesSetters = new HashMap<>();
// Abort the whole transformation if this operation fails
private boolean abortOnFailure = false;
@@ -131,7 +120,7 @@ public int getOrder() {
// Optional condition to let this operation be executed (if true)
// This is the actual UtilityCondition object to be executed
// right before this TU is executed. Its result is then evaluated
- // and, based on that, this TU is executed or not
+ // and, based on that, this T is executed or not
private UtilityCondition utilityCondition = null;
// Indicates whether or not this utility has already been
@@ -143,11 +132,13 @@ public int getOrder() {
// in the TCA
private AtomicBoolean hasBeenPerformed = new AtomicBoolean(false);
- /**
- * The public default constructor should always be available by any transformation
- * utility because in many cases all of its properties will be set during
- * transformation time, using the transformation context
- */
+ // Even though it is redundant to have this default constructor here, since it is
+ // the only one (the compiler would have added it implicitly), this is being explicitly
+ // set here to emphasize that the public default constructor should always be
+ // available by any transformation utility even when additional constructors are present.
+ // The reason for that is the fact that one or more of its properties might be set
+ // during transformation time, using the TransformationUtility set method
+ @SuppressWarnings("PMD.UnnecessaryConstructor")
public TransformationUtility() {
}
@@ -159,12 +150,12 @@ public TransformationUtility() {
* @param name transformation utility instance name
* @return this transformation utility instance
*/
- protected TU setName(String name) {
+ protected T setName(String name) {
if(StringUtils.isBlank(name)) {
throw new TransformationDefinitionException(name + " cannot be blank");
}
this.name = name;
- return (TU) this;
+ return (T) this;
}
public final String getName() {
@@ -180,9 +171,9 @@ public final String getName() {
* when saved into the transformation context.
* @return this transformation utility instance
*/
- public TU setContextAttributeName(String contextAttributeName) {
+ public T setContextAttributeName(String contextAttributeName) {
this.contextAttributeName = contextAttributeName;
- return (TU) this;
+ return (T) this;
}
/**
@@ -207,15 +198,15 @@ public String getContextAttributeName() {
* @param order the order of execution of this utility
* @return this transformation utility instance
*/
- public final TU setParent(TransformationUtilityParent parent, int order) {
+ public final T setParent(TransformationUtilityParent parent, int order) {
this.parent = parent;
this.order = order;
if(name == null) {
- setName(String.format(UTILITY_NAME_SYNTAX, parent.getName(), order, ((TU) this).getClass().getSimpleName()));
+ setName(String.format(UTILITY_NAME_SYNTAX, parent.getName(), order, ((T) this).getClass().getSimpleName()));
}
- return (TU) this;
+ return (T) this;
}
/**
@@ -252,6 +243,17 @@ public TransformationTemplate getTransformationTemplate() {
*/
public abstract String getDescription();
+ /**
+ * Returns the execution order for this utility on its parent.
+ * Value -1 means it has not been registered to any parent yet,
+ * while 1 means first.
+ *
+ * @return the execution order for this utility on its parent
+ */
+ public int getOrder() {
+ return order;
+ }
+
/**
* Sets the relative path from the application root folder
* to the file or folder the transformation utility should perform against.
@@ -270,21 +272,23 @@ public TransformationTemplate getTransformationTemplate() {
* to the file or folder the transformation utility should be performed against
* @return this transformation utility instance
*/
- public final TU relative(String relativePath) {
+ public final T relative(String relativePath) {
this.relativePath = normalizeRelativePathSeparator(relativePath);
- return (TU) this;
+ return (T) this;
}
/*
- * Returns a relative path that is in compliance with the current OS in terms of file separator
+ * Returns a relative path that is in compliance with the current OS in terms of file separator,
+ * or null, if the passed relative path is null
*/
- protected static String normalizeRelativePathSeparator(String _relativePath) {
- if(_relativePath != null) {
- _relativePath = _relativePath.replace('/', File.separatorChar).replace('\\', File.separatorChar);
+ protected static String normalizeRelativePathSeparator(String relativePath) {
+ String normalizedRelativePath = null;
+ if(relativePath != null) {
+ normalizedRelativePath = relativePath.replace('/', File.separatorChar).replace('\\', File.separatorChar);
}
- return _relativePath;
+ return normalizedRelativePath;
}
/**
@@ -321,8 +325,7 @@ private void setAbsoluteFile(File transformedAppFolder, TransformationContext tr
if(absoluteFile == null) {
String exceptionMessage = String.format("Context attribute %s, which is supposed to define absolute file for %s, is null", absoluteFileFromContextAttribute, name);
// FIXME a better exception is necessary here for cases when the absolute path transformation context attribute value is null
- TransformationUtilityException exception = new TransformationUtilityException(exceptionMessage);
- throw exception;
+ throw new TransformationUtilityException(exceptionMessage);
}
if(additionalRelativePath != null) {
absoluteFile = new File(absoluteFile, additionalRelativePath);
@@ -337,8 +340,7 @@ private void setAbsoluteFile(File transformedAppFolder, TransformationContext tr
} else {
if (relativePath == null) {
String exceptionMessage = String.format("Neither absolute nor relative path has been set for transformation utility %s", name);
- TransformationUtilityException exception = new TransformationUtilityException(exceptionMessage);
- throw exception;
+ throw new TransformationUtilityException(exceptionMessage);
}
absoluteFile = new File(transformedAppFolder, relativePath);
}
@@ -394,17 +396,17 @@ public static String getRelativePath(File baselineFile, File targetFile) {
* execution
* @return this transformation utility instance
*/
- public final TU set(String propertyName, String contextAttributeName) {
+ public final T set(String propertyName, String contextAttributeName) {
Method method = getMethod(propertyName);
latePropertiesAttributes.put(propertyName, contextAttributeName);
latePropertiesSetters.put(propertyName, method);
- return (TU) this;
+ return (T) this;
}
private Method getMethod(String propertyName) {
String methodName = getMethodName(propertyName);
- Class clazz = ((TU) this).getClass();
+ Class clazz = ((T) this).getClass();
for(Method method : clazz.getMethods()) {
if(method.getName().equals(methodName)) {
@@ -431,7 +433,7 @@ protected final void applyPropertiesFromContext(TransformationContext transforma
Method method;
Object value = null;
for (final Iterator itr = latePropertiesAttributes.entrySet().iterator(); itr.hasNext();) {
- Map.Entry entry = (Map.Entry)itr.next();
+ Map.Entry entry = (Map.Entry) itr.next();
String propertyName = entry.getKey();
attributeName = latePropertiesAttributes.get(propertyName);
try {
@@ -488,9 +490,9 @@ private String getMethodName(String propertyName) {
* execution
* @return this transformation utility instance
*/
- public TU absolute(String contextAttributeName) {
+ public T absolute(String contextAttributeName) {
absoluteFileFromContextAttribute = contextAttributeName;
- return (TU) this;
+ return (T) this;
}
/**
@@ -513,14 +515,14 @@ public TU absolute(String contextAttributeName) {
* in {@link #relative(String)}
* @return this transformation utility instance
*/
- public TU absolute(String contextAttributeName, String additionalRelativePath) {
+ public T absolute(String contextAttributeName, String additionalRelativePath) {
absoluteFileFromContextAttribute = contextAttributeName;
this.additionalRelativePath = normalizeRelativePathSeparator(additionalRelativePath);
- return (TU) this;
+ return (T) this;
}
- final String getAbsoluteFileFromContextAttribute() {
+ private final String getAbsoluteFileFromContextAttribute() {
return absoluteFileFromContextAttribute;
}
@@ -572,22 +574,21 @@ public PerformResult perform(File transformedAppFolder, TransformationContext tr
// Checking for UtilityCondition condition
if(utilityCondition != null) {
- try {
- TransformationUtility utilityCondition = this.utilityCondition.clone();
- utilityCondition.relative(this.getRelativePath());
- TUExecutionResult conditionExecutionResult = (TUExecutionResult) utilityCondition.execution(transformedAppFolder, transformationContext);
- Object conditionResult = conditionExecutionResult.getValue();
- if (conditionResult == null || conditionResult instanceof Boolean && !((Boolean) conditionResult).booleanValue()) {
- String utilityConditionName = (utilityCondition.getName() == null ? utilityCondition.toString() : utilityCondition.getName());
- String details = String.format("%s was skipped due to failing UtilityCondition '%s'", getName(), utilityConditionName);
- return PerformResult.skippedCondition(this, details);
- }
- } catch (CloneNotSupportedException e) {
- String exceptionMessage = String.format("%s can't be executed because the UtilityCondition object associated with it can't be cloned", getName());
- TransformationUtilityException ex = new TransformationUtilityException(exceptionMessage, e);
- return PerformResult.error(this, ex);
- }
+ TransformationUtility utilityCondition = this.utilityCondition.copy();
+
+ // Setting the condition to execute against the exact same file this TU is set to execute against
+ utilityCondition.relativePath = this.relativePath;
+ utilityCondition.absoluteFile = this.absoluteFile;
+ utilityCondition.absoluteFileFromContextAttribute = this.absoluteFileFromContextAttribute;
+ utilityCondition.additionalRelativePath = this.additionalRelativePath;
+ TUExecutionResult conditionExecutionResult = (TUExecutionResult) utilityCondition.execution(transformedAppFolder, transformationContext);
+ Object conditionResult = conditionExecutionResult.getValue();
+ if (conditionResult == null || conditionResult instanceof Boolean && !((Boolean) conditionResult).booleanValue()) {
+ String utilityConditionName = (utilityCondition.getName() == null ? utilityCondition.toString() : utilityCondition.getName());
+ String details = String.format("%s was skipped due to failing UtilityCondition '%s'", getName(), utilityConditionName);
+ return PerformResult.skippedCondition(this, details);
+ }
}
// Checking for dependencies
@@ -639,9 +640,9 @@ public PerformResult perform(File transformedAppFolder, TransformationContext tr
* If not, just state a warning, aborts the operation execution only
* @return this transformation utility instance
*/
- public final TU abortOnFailure(boolean abort) {
+ public final T abortOnFailure(boolean abort) {
abortOnFailure = abort;
- return (TU) this;
+ return (T) this;
}
/**
@@ -657,10 +658,10 @@ public final TU abortOnFailure(boolean abort) {
* has to be aborted
* @return this transformation utility instance
*/
- public final TU abortOnFailure(boolean abort, String abortionMessage) {
+ public final T abortOnFailure(boolean abort, String abortionMessage) {
abortOnFailure = abort;
this.abortionMessage = abortionMessage;
- return (TU) this;
+ return (T) this;
}
/**
@@ -716,9 +717,9 @@ public boolean isSaveResult() {
* context object
* @return this transformation utility instance
*/
- protected TU setSaveResult(boolean saveResult) {
+ protected T setSaveResult(boolean saveResult) {
this.saveResult = saveResult;
- return (TU) this;
+ return (T) this;
}
/**
@@ -739,7 +740,7 @@ public final boolean hasBeenPerformed() {
*
*
If TU B depends on TU A, and if TU A "fails"
* but doesn't abort transformation, then TU B would be skipped
- *
If TU B depends on TU A, then that means TU A is necessary supposed to be executed first,
+ *
If TU B depends on TU A, then that means TU A is necessarily supposed to be executed first,
* if not, TU B will be skipped
*
* The term "fails" in this context means the perform result is of one of these types:
@@ -758,24 +759,24 @@ public final boolean hasBeenPerformed() {
*
* See also:
*
*
* @param dependencies the names of all transformation utilities this utility depends on
* @return this transformation utility instance
*/
- public final TU dependsOn(String... dependencies) {
+ public final T dependsOn(String... dependencies) {
if (dependencies != null) {
for (String dependency : dependencies) {
if (StringUtils.isBlank(dependency)) throw new IllegalArgumentException("Dependencies cannot be null nor blank");
}
}
this.dependencies = dependencies;
- return (TU) this;
+ return (T) this;
}
/**
@@ -847,9 +848,9 @@ protected Result checkDependencies(TransformationContext transformationContext)
* utility should be executed or not
* @return this transformation utility instance
*/
- public final TU executeIf(String conditionAttributeName) {
+ public final T executeIf(String conditionAttributeName) {
this.ifConditionAttributeName = conditionAttributeName;
- return (TU) this;
+ return (T) this;
}
/**
@@ -859,19 +860,18 @@ public final TU executeIf(String conditionAttributeName) {
* Differences between this approach and {@link #executeIf(String)}:
*
*
Instead of relying on a TCA ({@link TransformationContext attribute}) with the condition result, this method is based on the direct execution of the {@link UtilityCondition} object
- *
The {@link UtilityCondition} object is always executed necessarily against the same file. Because of that, any value set on it via {@link #relative(String)} or {@link #absolute(String)} is ignored.
+ *
The {@link UtilityCondition} object is always executed necessarily against the same file set in the transformation utility it is being used. Because of that, any value set in the condition itself via {@link #relative(String)} or {@link #absolute(String)} is ignored.
*
The {@link UtilityCondition} object does not produce any TCA, neither its result value or result object. Instead, it hands its result directly to the TU, so that the condition can be evaluated just before the TU executes (or not, if it fails).
*
The {@link UtilityCondition} object does not exist from a transformation template point of view. That means this method is totally different than adding a new {@link UtilityCondition} object by calling {@link TransformationTemplate#add(TransformationUtility)}.
- *
No TU can {@link #dependsOn(String...)} this {@link UtilityCondition} object.
*
- * The actual {@link UtilityCondition} object is not the one used, but a clone of it
+ * The actual {@link UtilityCondition} object is not the one used, but a copy of it
*
* @param utilityCondition the condition to be executed and evaluated right before this TU
* @return this transformation utility instance
*/
- public final TU executeIf(UtilityCondition utilityCondition) {
+ public final T executeIf(UtilityCondition utilityCondition) {
this.utilityCondition = utilityCondition;
- return (TU) this;
+ return (T) this;
}
/**
@@ -884,9 +884,9 @@ public final TU executeIf(UtilityCondition utilityCondition) {
* utility should be executed or not
* @return this transformation utility instance
*/
- public final TU executeUnless(String conditionAttributeName) {
+ public final T executeUnless(String conditionAttributeName) {
this.unlessConditionAttributeName = conditionAttributeName;
- return (TU) this;
+ return (T) this;
}
/**
@@ -953,77 +953,65 @@ public String toString() {
return getDescription();
}
+
+ /**
+ * Creates and returns a clone object identical to the original object,
+ * except for the "has been performed" flag, which is set to {@code false}
+ * in the clone object to be returned. See {@link #hasBeenPerformed()}.
+ *
+ * @return the new object created as result of the clone operation
+ */
@Override
- public TransformationUtility clone() throws CloneNotSupportedException {
- TransformationUtility clone = (TransformationUtility) super.clone();
+ public T clone() {
+ TransformationUtility clone = null;
+ try {
+ clone = (TransformationUtility) super.clone();
+ } catch (CloneNotSupportedException e) {
+ // This should never happen though, since this class DOES support clone operations
+ throw new TransformationUtilityException("Unexpected exception happened when cloning the transformation utility instance", e);
+ }
- // Properties we do NOT want to be in the clone (they are being initialized)
+ // Properties we do NOT want to be cloned (they are being initialized)
clone.hasBeenPerformed = new AtomicBoolean(false);
- // Properties we want to be in the clone (they are being copied from original object)
- clone.order = this.order;
- clone.parent = this.parent;
- clone.name = this.name;
- clone.relativePath = this.relativePath;
- clone.absoluteFile = this.absoluteFile;
- clone.absoluteFileFromContextAttribute = this.absoluteFileFromContextAttribute;
- clone.additionalRelativePath = this.additionalRelativePath;
- clone.contextAttributeName = this.contextAttributeName;
+ // Non-primitive and mutable object properties that need to be manually cloned from original object
+ if (absoluteFile != null) clone.absoluteFile = new File(this.absoluteFile.getAbsolutePath());
clone.latePropertiesAttributes = new HashMap();
clone.latePropertiesSetters = new HashMap();
clone.latePropertiesAttributes.putAll(this.latePropertiesAttributes);
clone.latePropertiesSetters.putAll(this.latePropertiesSetters);
- clone.abortOnFailure = this.abortOnFailure;
- clone.saveResult = this.saveResult;
- clone.ifConditionAttributeName = this.ifConditionAttributeName;
- clone.unlessConditionAttributeName = this.unlessConditionAttributeName;
- clone.utilityCondition = this.utilityCondition;
- return clone;
+ return (T) clone;
}
/**
- * Creates and returns a brand new utility object using the original as a template,
- * and setting to the copy most of the attributes of the original one.
- * It will not copy though all attributes that define the identity of the original one, which are:
+ * Creates and returns a copy object similar to the original object.
+ * All attributes are the same, except for the following ones, which are reset:
*
*
parent
*
name
*
order
- *
file relative and absolute path
*
context attribute name
+ *
file relative and absolute path
+ *
has been performed flag
*
*
- * @return this transformation utility instance
- * @throws CloneNotSupportedException in case the concrete transformation utility
- * does not support being cloned
+ * @return the new object created as result of the copy operation
*/
- public TransformationUtility copy() throws CloneNotSupportedException {
- TransformationUtility copy = (TransformationUtility) super.clone();
+ public T copy() {
+ TransformationUtility copy = clone();
- // Properties we do NOT want to be in the copy (they are being initialized)
- copy.order = -1;
+ // Properties we do NOT want to be copied (they are being initialized)
copy.parent = null;
copy.name = null;
+ copy.order = -1;
+ copy.contextAttributeName = null;
copy.relativePath = "";
copy.absoluteFile = null;
copy.absoluteFileFromContextAttribute = null;
copy.additionalRelativePath = null;
- copy.contextAttributeName = null;
- copy.hasBeenPerformed = new AtomicBoolean(false);
-
- // Properties we want to be in the copy (they are being copied from original object)
- copy.latePropertiesAttributes = new HashMap();
- copy.latePropertiesSetters = new HashMap();
- copy.latePropertiesAttributes.putAll(this.latePropertiesAttributes);
- copy.latePropertiesSetters.putAll(this.latePropertiesSetters);
- copy.abortOnFailure = this.abortOnFailure;
- copy.saveResult = this.saveResult;
- copy.ifConditionAttributeName = this.ifConditionAttributeName;
- copy.unlessConditionAttributeName = this.unlessConditionAttributeName;
- copy.utilityCondition = this.utilityCondition;
-
- return copy;
+
+ return (T) copy;
}
/**
@@ -1087,6 +1075,7 @@ protected static void checkForNull(String name, Object value) throws Transformat
* @return true only if they are equal
*/
@Override
+ @SuppressWarnings("PMD.SimplifyBooleanReturns")
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof TransformationUtility)) return false;
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityGroup.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityGroup.java
index 9a574815..3f97e57e 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityGroup.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityGroup.java
@@ -21,6 +21,13 @@ public class TransformationUtilityGroup extends TransformationUtility clone() throws CloneNotSupportedException {
- TransformationUtilityGroup groupClone = (TransformationUtilityGroup) super.clone();
+ public TransformationUtilityGroup clone() {
+ TransformationUtilityGroup groupClone = super.clone();
groupClone.utilityList = new ArrayList<>();
groupClone.utilityNames = new HashSet<>();
for (TransformationUtility utility : utilityList) {
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityList.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityList.java
index 28485058..467a2467 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityList.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityList.java
@@ -49,12 +49,30 @@ interface TransformationUtilityList extends TransformationUtilityParent {
String addMultiple(TransformationOperation templateOperation, String... attributes);
/**
+ * This method has been deprecated. Use {@link #info(String)} instead.
+ *
* Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list
*
* @param logMessage the message to be logged
*/
+ @Deprecated
void log(String logMessage);
+ /**
+ * Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list,
+ * setting its log level to INFO
+ *
+ * @param infoMessage the info message to be logged
+ */
+ void info(String infoMessage);
+
+ /**
+ * Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list,
+ * setting its log level to DEBUG
+ *
+ * @param debugMessage the debug message to be logged
+ */
+ void debug(String debugMessage);
/**
* Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list
@@ -65,6 +83,8 @@ interface TransformationUtilityList extends TransformationUtilityParent {
void log(Level logLevel, String logMessage);
/**
+ * This method has been deprecated. Use {@link #info(String, String...)} instead.
+ *
* Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list.
* The log messages may contain placeholders to be replaced by transformation context
* attribute values. Use {@code {}} as placeholder marker.
@@ -74,8 +94,35 @@ interface TransformationUtilityList extends TransformationUtilityParent {
* @param attributeNames an array of names of transformation context attributes, whose values
* are going to be used in the log message
*/
+ @Deprecated
void log(String logMessage, String... attributeNames);
+ /**
+ * Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list,
+ * setting its log level to INFO.
+ * The log messages may contain placeholders to be replaced by transformation context
+ * attribute values. Use {@code {}} as placeholder marker.
+ *
+ * @param infoMessage the info message to be logged, containing {@code {}} placeholders to be replaced by
+ * transformation context attribute values
+ * @param attributeNames an array of names of transformation context attributes, whose values
+ * are going to be used in the log message
+ */
+ void info(String infoMessage, String... attributeNames);
+
+ /**
+ * Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list,
+ * setting its log level to DEBUG.
+ * The log messages may contain placeholders to be replaced by transformation context
+ * attribute values. Use {@code {}} as placeholder marker.
+ *
+ * @param debugMessage the debug message to be logged, containing {@code {}} placeholders to be replaced by
+ * transformation context attribute values
+ * @param attributeNames an array of names of transformation context attributes, whose values
+ * are going to be used in the log message
+ */
+ void debug(String debugMessage, String... attributeNames);
+
/**
* Adds a new {@link com.paypal.butterfly.extensions.api.utilities.Log} TU to the list.
* The log messages may contain placeholders to be replaced by transformation context
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityLoop.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityLoop.java
index 1a9fc5aa..77c29404 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityLoop.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/TransformationUtilityLoop.java
@@ -1,7 +1,6 @@
package com.paypal.butterfly.extensions.api;
import com.paypal.butterfly.extensions.api.exception.TransformationDefinitionException;
-import com.paypal.butterfly.extensions.api.exception.TransformationUtilityException;
import java.io.File;
import java.util.ArrayList;
@@ -9,12 +8,13 @@
import java.util.List;
/**
- * Allows the execution of a transformation utility instance, created from a template, multiple times in a loop.
- * The number of iterations is defined by one of these options, and in this order of precedence:
+ * Allows the execution of any transformation utility instance,
+ * including a {@link TransformationUtilityGroup}, multiple times in a loop.
+ * The number of iterations is defined by one of these options:
*
- *
Specifying the number of iterations
- *
Specifying a {@link TransformationContext} attribute (by its name) whose value is true or false. If not a boolean, or if non-existent, it will be treated as false
- *
Specifying a {@link TransformationUtility} object whose result is true or false. In this case, the TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false
+ *
Specifying the number of iterations.
+ *
Specifying a {@link TransformationContext} attribute (by its name) whose value is true or false. If that is not a boolean, or if non-existent, it will be treated as false. If that is false, the loop is interrupted.
+ *
Specifying a {@link UtilityCondition} object whose result is true or false. The result of this TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false. If that is false, the loop is interrupted.
*
*
* @author facarvalho
@@ -22,6 +22,8 @@
public class TransformationUtilityLoop extends TransformationUtility implements TransformationUtilityParent {
private static final String DESCRIPTION = "Transformation template loop, executing %s";
+ private static final String TEMPLATE_NAME_FORMAT = "%s_%s_template";
+ private static final String CONDITION_NAME_FORMAT = "%s_%s_condition";
// Possible ways to define the condition
private int iterations = -1;
@@ -35,16 +37,51 @@ public class TransformationUtilityLoop extends TransformationUtility childrenList = new ArrayList<>();
+ /**
+ * Allows the execution of any transformation utility instance,
+ * including a {@link TransformationUtilityGroup}, multiple times in a loop.
+ * The number of iterations is defined by one of these options:
+ *
+ *
Specifying the number of iterations.
+ *
Specifying a {@link TransformationContext} attribute (by its name) whose value is true or false. If that is not a boolean, or if non-existent, it will be treated as false. If that is false, the loop is interrupted.
+ *
Specifying a {@link UtilityCondition} object whose result is true or false. The result of this TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false. If that is false, the loop is interrupted.
+ *
+ */
public TransformationUtilityLoop() {
}
+ /**
+ * Allows the execution of any transformation utility instance,
+ * including a {@link TransformationUtilityGroup}, multiple times in a loop.
+ * The number of iterations is defined by one of these options:
+ *
+ *
Specifying the number of iterations.
+ *
Specifying a {@link TransformationContext} attribute (by its name) whose value is true or false. If that is not a boolean, or if non-existent, it will be treated as false. If that is false, the loop is interrupted.
+ *
Specifying a {@link UtilityCondition} object whose result is true or false. The result of this TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false. If that is false, the loop is interrupted.
+ *
+ *
+ * @param template the transformation utility instance to be used a template.
+ * A clone utility instance will be created out of the template
+ * for each iteration. See {@link #clone()} for further information
+ * about the clone object.
+ */
public TransformationUtilityLoop(TransformationUtility template) {
setTemplate(template);
}
+ /**
+ * Sets the transformation utility instance to be used as a template.
+ * A clone utility instance will be created out of the template
+ * for each iteration. See {@link #clone()} for further information
+ * about the clone object.
+ *
+ * @param template the transformation utility instance to be used as template.
+ * @return this transformation utility instance
+ */
public TransformationUtilityLoop setTemplate(TransformationUtility template) {
checkForNull("template", template);
@@ -52,17 +89,29 @@ public TransformationUtilityLoop setTemplate(TransformationUtility template) {
String exceptionMessage = String.format("Invalid attempt to add already registered transformation utility %s to transformation utility loop %s", template.getName(), getName());
throw new TransformationDefinitionException(exceptionMessage);
}
+
+ // Why is this check necessary? What if the TU template is not based on a file?
if (!template.isFileSet()) {
String exceptionMessage = String.format("Neither absolute, nor relative path, have been set for transformation utility %s", template.getName());
throw new TransformationDefinitionException(exceptionMessage);
}
- template.setParent(this, 1);
+
+ // Even though the template have the loop TU set as its parent, the order is set to 0, and it is not added a child of the loop,
+ // since it is not in fact executed (only the instances cloned out of the template are)
+ template.setParent(this, 0);
this.template = template;
- childrenList.add(template);
return this;
}
+ /**
+ * In this case the condition to execute the next iteration is based on
+ * a pre-defined number of iterations to be executed. Each execution
+ * decrease the remaining number of iterations.
+ *
+ * @param iterations the total number of iterations to be executed
+ * @return this transformation utility instance
+ */
public TransformationUtilityLoop setCondition(int iterations) {
if (iterations < 2) {
throw new TransformationDefinitionException("The number of iterations should be equal or greater than 2");
@@ -71,12 +120,37 @@ public TransformationUtilityLoop setCondition(int iterations) {
return this;
}
+ /**
+ * In this case the condition to execute the next iteration is based on
+ * a {@link TransformationContext} attribute (specified by its name) whose
+ * value is true or false. If that is not a boolean, or if non-existent,
+ * it will be treated as false. If that is false, the loop is interrupted.
+ *
+ * @param attribute the name of the transformation context attribute
+ * holding the boolean to be used as the condition
+ * to execute the next iteration. If that is false,
+ * the loop is interrupted.
+ * @return this transformation utility instance
+ */
public TransformationUtilityLoop setCondition(String attribute) {
checkForBlankString("attribute", attribute);
this.attribute = attribute;
return this;
}
+ /**
+ * In this case the condition to execute the next iteration is based on
+ * a {@link UtilityCondition} object whose result is true or false.
+ * The result of this TU condition object won't be saved to the TC,
+ * it will be executed exclusively to the scope of this loop execution.
+ * Any result other than a boolean true value, including failures, will be treated as false.
+ * If that is false, the loop is interrupted.
+ *
+ * @param condition the {@link UtilityCondition} object whose result
+ * will be used as the condition to execute the next iteration.
+ * If that is false, the loop is interrupted.
+ * @return this transformation utility instance
+ */
public TransformationUtilityLoop setCondition(UtilityCondition condition) {
checkForNull("condition", condition);
if (condition.getName() == null && getName() != null) {
@@ -86,9 +160,6 @@ public TransformationUtilityLoop setCondition(UtilityCondition condition) {
return this;
}
- private static final String TEMPLATE_NAME_FORMAT = "%s_%s_template";
- private static final String CONDITION_NAME_FORMAT = "%s_%s_condition";
-
@Override
protected TransformationUtilityLoop setName(String name) {
super.setName(name);
@@ -152,12 +223,7 @@ protected ExecutionResult execution(File transformedAppFolder, TransformationCon
iterateAgain = attributeValue instanceof Boolean && ((Boolean) attributeValue).booleanValue();
} else if (condition != null) {
TUExecutionResult executionResult = null;
- try {
- executionResult = (TUExecutionResult) condition.clone().execution(transformedAppFolder, transformationContext);
- } catch (CloneNotSupportedException e) {
- TransformationUtilityException tue = new TransformationUtilityException("The condition transformation utility is not cloneable", e);
- return TUExecutionResult.error(this, tue);
- }
+ executionResult = (TUExecutionResult) condition.clone().execution(transformedAppFolder, transformationContext);
if (executionResult.getType().equals(TUExecutionResult.Type.VALUE)) {
Object executionValue = executionResult.getValue();
iterateAgain = executionValue instanceof Boolean && ((Boolean) executionValue).booleanValue();
@@ -183,11 +249,11 @@ protected ExecutionResult execution(File transformedAppFolder, TransformationCon
* @return the TU instance to be run in this iteration
*/
public TransformationUtility run() {
- try {
- return template.clone();
- } catch (CloneNotSupportedException e) {
- throw new TransformationUtilityException("The template transformation template is not cloneable", e);
- }
+ TransformationUtility iterationClone = template.clone();
+ iterationClone.setParent(this, nextIteration);
+ childrenList.add(iterationClone);
+
+ return iterationClone;
}
/**
@@ -197,11 +263,7 @@ public TransformationUtility run() {
*/
public TransformationUtility iterate() {
nextIteration++;
- try {
- return clone();
- } catch (CloneNotSupportedException e) {
- throw new TransformationUtilityException("This transformation utility loop is not cloneable", e);
- }
+ return clone();
}
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/UtilityCondition.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/UtilityCondition.java
index e81d1442..82b601fb 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/UtilityCondition.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/UtilityCondition.java
@@ -19,5 +19,5 @@
*
* @author facarvalho
*/
-public abstract class UtilityCondition extends TransformationUtility {
+public abstract class UtilityCondition extends TransformationUtility {
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/metrics/AbortDetails.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/metrics/AbortDetails.java
index d1fe1865..b8275f7f 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/metrics/AbortDetails.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/metrics/AbortDetails.java
@@ -9,11 +9,11 @@
*/
public class AbortDetails {
- String utilityName;
- String abortMessage;
- String exceptionClass;
- String exceptionMessage;
- String exceptionStackTrace;
+ private String utilityName;
+ private String abortMessage;
+ private String exceptionClass;
+ private String exceptionMessage;
+ private String exceptionStackTrace;
public AbortDetails(Exception ex, String abortMessage, String utilityName) {
if (ex == null) {
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElement.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElement.java
index 164a0f6d..31c6d3fb 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElement.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElement.java
@@ -22,7 +22,7 @@
*
* @author facarvalho
*/
-public interface AddElement {
+public interface AddElement {
/**
* Possible behaviors in case the element to be added already exists.
@@ -63,7 +63,7 @@ enum IfPresent {
*
* @return the transformation operation instance
*/
- TO failIfPresent();
+ T failIfPresent();
/**
* Warn and do not add ({@link com.paypal.butterfly.extensions.api.TOExecutionResult.Type#WARNING})
@@ -71,7 +71,7 @@ enum IfPresent {
*
* @return the transformation operation instance
*/
- TO warnNotAddIfPresent();
+ T warnNotAddIfPresent();
/**
* Warn, but add, ({@link com.paypal.butterfly.extensions.api.TOExecutionResult.Type#WARNING})
@@ -79,7 +79,7 @@ enum IfPresent {
*
* @return the transformation operation instance
*/
- TO warnButAddIfPresent();
+ T warnButAddIfPresent();
/**
* Do nothing, not add, not warn neither fail, ({@link com.paypal.butterfly.extensions.api.TOExecutionResult.Type#NO_OP})
@@ -87,7 +87,7 @@ enum IfPresent {
*
* @return the transformation operation instance
*/
- TO noOpIfPresent();
+ T noOpIfPresent();
/**
* Overwrite and not warn ({@link com.paypal.butterfly.extensions.api.TOExecutionResult.Type#SUCCESS})
@@ -95,6 +95,6 @@ enum IfPresent {
*
* @return the transformation operation instance
*/
- TO overwriteIfPresent();
+ T overwriteIfPresent();
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElementTO.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElementTO.java
index 083d1cd7..db83c92d 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElementTO.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/AddElementTO.java
@@ -9,39 +9,39 @@
*
* @author facarvalho
*/
-public abstract class AddElementTO extends TransformationOperation implements AddElement {
+public abstract class AddElementTO extends TransformationOperation implements AddElement {
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings (value="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification="This property will be used by sub-classes")
protected IfPresent ifPresent = IfPresent.Fail;
@Override
- public TO failIfPresent() {
+ public T failIfPresent() {
ifPresent = IfPresent.Fail;
- return (TO) this;
+ return (T) this;
}
@Override
- public TO warnNotAddIfPresent() {
+ public T warnNotAddIfPresent() {
ifPresent = IfPresent.WarnNotAdd;
- return (TO) this;
+ return (T) this;
}
@Override
- public TO warnButAddIfPresent() {
+ public T warnButAddIfPresent() {
ifPresent = IfPresent.WarnButAdd;
- return (TO) this;
+ return (T) this;
}
@Override
- public TO noOpIfPresent() {
+ public T noOpIfPresent() {
ifPresent = IfPresent.NoOp;
- return (TO) this;
+ return (T) this;
}
@Override
- public TO overwriteIfPresent() {
+ public T overwriteIfPresent() {
ifPresent = IfPresent.Overwrite;
- return (TO) this;
+ return (T) this;
}
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElement.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElement.java
index 706ec745..ede110e7 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElement.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElement.java
@@ -22,7 +22,7 @@
*
* @author facarvalho
*/
-public interface ChangeOrRemoveElement {
+public interface ChangeOrRemoveElement {
/**
* Possible behaviors in case the element to be changed or removed is not present.
@@ -53,7 +53,7 @@ enum IfNotPresent {
*
* @return the transformation operation instance
*/
- TO failIfNotPresent();
+ T failIfNotPresent();
/**
* Warn ({@link com.paypal.butterfly.extensions.api.TOExecutionResult.Type#WARNING})
@@ -61,7 +61,7 @@ enum IfNotPresent {
*
* @return the transformation operation instance
*/
- TO warnIfNotPresent();
+ T warnIfNotPresent();
/**
* Do nothing, not warn neither fail, ({@link com.paypal.butterfly.extensions.api.TOExecutionResult.Type#NO_OP})
@@ -69,6 +69,6 @@ enum IfNotPresent {
*
* @return the transformation operation instance
*/
- TO noOpIfNotPresent();
+ T noOpIfNotPresent();
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElementTO.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElementTO.java
index e50c918c..b4438a51 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElementTO.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/operations/ChangeOrRemoveElementTO.java
@@ -9,27 +9,27 @@
*
* @author facarvalho
*/
-public abstract class ChangeOrRemoveElementTO extends TransformationOperation implements ChangeOrRemoveElement {
+public abstract class ChangeOrRemoveElementTO extends TransformationOperation implements ChangeOrRemoveElement {
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings (value="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification="This property will be used by sub-classes")
protected IfNotPresent ifNotPresent = IfNotPresent.Fail;
@Override
- public TO failIfNotPresent() {
+ public T failIfNotPresent() {
ifNotPresent = IfNotPresent.Fail;
- return (TO) this;
+ return (T) this;
}
@Override
- public TO warnIfNotPresent() {
+ public T warnIfNotPresent() {
ifNotPresent = IfNotPresent.Warn;
- return (TO) this;
+ return (T) this;
}
@Override
- public TO noOpIfNotPresent() {
+ public T noOpIfNotPresent() {
ifNotPresent = IfNotPresent.NoOp;
- return (TO) this;
+ return (T) this;
}
}
diff --git a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/upgrade/UpgradePath.java b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/upgrade/UpgradePath.java
index fd948300..6f2ad27f 100644
--- a/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/upgrade/UpgradePath.java
+++ b/butterfly-extensions-api/src/main/java/com/paypal/butterfly/extensions/api/upgrade/UpgradePath.java
@@ -40,6 +40,7 @@ public UpgradePath(Class extends UpgradeStep> firstStepClass) {
this(firstStepClass, null);
}
+ @SuppressWarnings("PMD.AvoidReassigningParameters")
public UpgradePath(Class extends UpgradeStep> firstStepClass, String upgradeVersion) {
if (firstStepClass == null) {
throw new IllegalArgumentException("First step class cannot be null");
diff --git a/butterfly-extensions-api/src/main/resources/stylesheet.css b/butterfly-extensions-api/src/main/resources/stylesheet.css
index fcd03174..c4f6312c 100644
--- a/butterfly-extensions-api/src/main/resources/stylesheet.css
+++ b/butterfly-extensions-api/src/main/resources/stylesheet.css
@@ -394,10 +394,7 @@ Table styles
.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
white-space:nowrap;
- padding-top:5px;
- padding-left:12px;
- padding-right:12px;
- padding-bottom:7px;
+ padding:5px 12px 7px 12px;
display:inline-block;
float:left;
background-color:#F8981D;
diff --git a/butterfly-facade/pom.xml b/butterfly-facade/pom.xml
index dc60199c..8f9516ca 100644
--- a/butterfly-facade/pom.xml
+++ b/butterfly-facade/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-facade/src/main/java/com/paypal/butterfly/facade/ButterflyFacade.java b/butterfly-facade/src/main/java/com/paypal/butterfly/facade/ButterflyFacade.java
index 4bde5fda..cf903b68 100644
--- a/butterfly-facade/src/main/java/com/paypal/butterfly/facade/ButterflyFacade.java
+++ b/butterfly-facade/src/main/java/com/paypal/butterfly/facade/ButterflyFacade.java
@@ -53,6 +53,7 @@ public interface ButterflyFacade {
* @param applicationFolder application folder
* @param templateClassName transformation template class name
* @return the transformation result object
+ * @throws ButterflyException in case the transformation did not succeed
*/
TransformationResult transform(File applicationFolder, String templateClassName) throws ButterflyException;
@@ -64,6 +65,7 @@ public interface ButterflyFacade {
* @param templateClassName transformation template class name
* @param configuration Butterfly configuration object
* @return the transformation result object
+ * @throws ButterflyException in case the transformation did not succeed
*/
TransformationResult transform(File applicationFolder, String templateClassName, Configuration configuration) throws ButterflyException;
@@ -73,6 +75,7 @@ public interface ButterflyFacade {
* @param applicationFolder application folder
* @param templateClass transformation template class
* @return the transformation result object
+ * @throws ButterflyException in case the transformation did not succeed
*/
TransformationResult transform(File applicationFolder, Class extends TransformationTemplate> templateClass) throws ButterflyException;
@@ -84,6 +87,7 @@ public interface ButterflyFacade {
* @param templateClass transformation template class
* @param configuration Butterfly configuration object
* @return the transformation result object
+ * @throws ButterflyException in case the transformation did not succeed
*/
TransformationResult transform(File applicationFolder, Class extends TransformationTemplate> templateClass, Configuration configuration) throws ButterflyException;
@@ -93,6 +97,7 @@ public interface ButterflyFacade {
* @param applicationFolder application folder
* @param upgradePath upgrade path object used to upgrade this application
* @return the transformation result object
+ * @throws ButterflyException in case the transformation did not succeed
*/
TransformationResult transform(File applicationFolder, UpgradePath upgradePath) throws ButterflyException;
@@ -104,6 +109,7 @@ public interface ButterflyFacade {
* @param upgradePath upgrade path object used to upgrade this application
* @param configuration Butterfly configuration object
* @return the transformation result object
+ * @throws ButterflyException in case the transformation did not succeed
*/
TransformationResult transform(File applicationFolder, UpgradePath upgradePath, Configuration configuration) throws ButterflyException;
diff --git a/butterfly-facade/src/main/java/com/paypal/butterfly/facade/Configuration.java b/butterfly-facade/src/main/java/com/paypal/butterfly/facade/Configuration.java
index dcf4f4ba..0828b68f 100644
--- a/butterfly-facade/src/main/java/com/paypal/butterfly/facade/Configuration.java
+++ b/butterfly-facade/src/main/java/com/paypal/butterfly/facade/Configuration.java
@@ -25,12 +25,11 @@ public Configuration() {
}
/**
- * @see {@link Configuration}
- * @see {@link #setOutputFolder(File)}
- * @see {@link #setZipOutput(boolean)}
+ * Butterfly default configuration
*
- * @param outputFolder
- * @param zipOutput
+ * @param outputFolder the output folder where the transformed application is
+ * supposed to be placed
+ * @param zipOutput if true, the transformed application folder will be compressed into a zip file
*/
public Configuration(File outputFolder, boolean zipOutput) {
setOutputFolder(outputFolder);
@@ -40,7 +39,7 @@ public Configuration(File outputFolder, boolean zipOutput) {
/**
* The folder location in the file system where the transformed application
* should be placed.
- *
+ *
* If null, it defaults to same location where original application is.
* n this case the transformed application is placed under a new folder
* whose named is same as original folder, plus a "-transformed-yyyyMMddHHmmssSSS"
@@ -58,42 +57,41 @@ public void setOutputFolder(File outputFolder) {
/**
* If set to true, the transformed application folder will be compressed
- * to a zip file, and the transformed folder will be removed. The zip
+ * into a zip file, and the transformed folder will be removed. The zip
* file will be named as the transformed application folder,
* plus the zip extension
*
- * @param zipOutput
+ * @param zipOutput if true, the transformed application folder will be compressed into a zip file
*/
public void setZipOutput(boolean zipOutput) {
this.zipOutput = zipOutput;
}
/**
- * @see {@link #setOutputFolder(File)}
+ * Return the folder where the transformed application is supposed to be placed
*
- * @return
+ * @return the folder where the transformed application is supposed to be placed
*/
public File getOutputFolder() {
return outputFolder;
}
/**
- * @see {@link #setZipOutput(boolean)}
+ * Returns whether the transformed application folder will be compressed into a zip file or not
*
- * @return
+ * @return whether the transformed application folder will be compressed into a zip file or not
*/
public boolean isZipOutput() {
return zipOutput;
}
- private static final String TO_STRING_FORMAT = "{ outputFolder: %s , zipOutput: %s }";
-
@Override
public String toString() {
- return String.format(TO_STRING_FORMAT, outputFolder, zipOutput);
+ return String.format("{ outputFolder: %s , zipOutput: %s }", outputFolder, zipOutput);
}
@Override
+ @SuppressWarnings("PMD.SimplifyBooleanReturns")
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -108,7 +106,7 @@ public boolean equals(Object obj) {
return false;
}
final Configuration configuration = (Configuration)obj;
- if(!(this.zipOutput == configuration.isZipOutput())) {
+ if(this.zipOutput != configuration.isZipOutput()) {
return false;
}
if (this.outputFolder == null && configuration.getOutputFolder() != null) {
diff --git a/butterfly-metrics-couchdb/pom.xml b/butterfly-metrics-couchdb/pom.xml
index 2f6a81a9..c2ca096d 100644
--- a/butterfly-metrics-couchdb/pom.xml
+++ b/butterfly-metrics-couchdb/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-metrics-file/pom.xml b/butterfly-metrics-file/pom.xml
index ba30c8ee..302fb9ae 100644
--- a/butterfly-metrics-file/pom.xml
+++ b/butterfly-metrics-file/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-utilities/pom.xml b/butterfly-utilities/pom.xml
index 71b2ecbc..7124898b 100644
--- a/butterfly-utilities/pom.xml
+++ b/butterfly-utilities/pom.xml
@@ -5,7 +5,7 @@
com.paypal.butterflybutterfly-parent
- 2.1.0
+ 2.2.0..
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareFiles.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareFiles.java
index 17a4c8eb..b5c68ad7 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareFiles.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareFiles.java
@@ -1,6 +1,8 @@
package com.paypal.butterfly.utilities.conditions;
import com.paypal.butterfly.extensions.api.DoubleCondition;
+import com.paypal.butterfly.extensions.api.TUExecutionResult;
+import com.paypal.butterfly.extensions.api.TransformationContext;
import com.paypal.butterfly.extensions.api.exception.TransformationUtilityException;
import org.apache.commons.io.FileUtils;
@@ -8,7 +10,8 @@
import java.io.IOException;
/**
- * Compares two files and returns true only if their contents are identical.
+ * Compares two files and returns true if the content of the files are equal,
+ * or if they both don't exist. Returns false otherwise.
*
* See {@link com.paypal.butterfly.extensions.api.DoubleCondition} to find out how to set the baseline and the comparison files
*
@@ -18,6 +21,28 @@ public class CompareFiles extends DoubleCondition {
private static final String DESCRIPTION = "Compare file %s to another one, return true only if their contents are equal";
+ /**
+ * Compares two files and returns true if the content of the files are equal,
+ * or if they both don't exist. Returns false otherwise.
+ *
+ * See {@link com.paypal.butterfly.extensions.api.DoubleCondition} to find out how to set the baseline and the comparison files
+ */
+ public CompareFiles(){
+ }
+
+ /**
+ * Compares two files and returns true if the content of the files are equal,
+ * or if they both don't exist. Returns false otherwise.
+ *
+ * See {@link com.paypal.butterfly.extensions.api.DoubleCondition} to find out how to set the baseline and the comparison files
+ *
+ * @param attribute the name of the transformation context attribute
+ * that refers to the file to be compared against the baseline file
+ */
+ public CompareFiles(String attribute){
+ super(attribute);
+ }
+
@Override
protected boolean compare(File baselineFile, File comparisonFile) {
try {
@@ -32,4 +57,9 @@ public String getDescription() {
return String.format(DESCRIPTION, getRelativePath());
}
+ @Override
+ protected TUExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
+ return super.execution(transformedAppFolder, transformationContext);
+ }
+
}
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareXMLFiles.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareXMLFiles.java
index ba341245..3b19798d 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareXMLFiles.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/CompareXMLFiles.java
@@ -1,6 +1,8 @@
package com.paypal.butterfly.utilities.conditions;
import com.paypal.butterfly.extensions.api.DoubleCondition;
+import com.paypal.butterfly.extensions.api.TUExecutionResult;
+import com.paypal.butterfly.extensions.api.TransformationContext;
import com.paypal.butterfly.extensions.api.exception.TransformationUtilityException;
import org.custommonkey.xmlunit.XMLUnit;
import org.w3c.dom.Document;
@@ -13,9 +15,10 @@
import java.io.IOException;
/**
- * Compares two XML files and returns true only
-if their contents are equal. Attribute orders, comments and white
- * spaces are ignored during the comparison.
+ * Compares two XML files and returns true if their contents are equal,
+ * or if both files don't exist. Returns false otherwise.
+ * Attribute orders, comments and white spaces are ignored during the comparison.
+ * It results in error if any of the two files is not a well formed XML file.
*
* See {@link DoubleCondition}
* to find out how to set the baseline and the comparison files
@@ -26,6 +29,34 @@ public class CompareXMLFiles extends DoubleCondition {
private static final String DESCRIPTION = "Compare XML file %s to another one, return true only if their contents are equal";
+ /**
+ * Compares two XML files and returns true if their contents are equal,
+ * or if both files don't exist. Returns false otherwise.
+ * Attribute orders, comments and white spaces are ignored during the comparison.
+ * It results in error if any of the two files is not a well formed XML file.
+ *
+ * See {@link DoubleCondition}
+ * to find out how to set the baseline and the comparison files
+ */
+ public CompareXMLFiles() {
+ }
+
+ /**
+ * Compares two XML files and returns true if their contents are equal,
+ * or if both files don't exist. Returns false otherwise.
+ * Attribute orders, comments and white spaces are ignored during the comparison.
+ * It results in error if any of the two files is not a well formed XML file.
+ *
+ * See {@link DoubleCondition}
+ * to find out how to set the baseline and the comparison files
+ *
+ * @param attribute the name of the transformation context attribute
+ * that refers to the file to be compared against the baseline file
+ */
+ public CompareXMLFiles(String attribute) {
+ setAttribute(attribute);
+ }
+
@Override
protected boolean compare(File baselineFile, File comparisonFile) {
try {
@@ -49,10 +80,15 @@ protected boolean compare(File baselineFile, File comparisonFile) {
return XMLUnit.compareXML(baselineXml, comparisonXml).similar();
} catch (SAXException | IOException | ParserConfigurationException e) {
- throw new TransformationUtilityException("An exception has happened when comparing the two XML files", e);
+ throw new TransformationUtilityException("An exception happened when comparing the two XML files", e);
}
}
+ @Override
+ protected TUExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
+ return super.execution(transformedAppFolder, transformationContext);
+ }
+
@Override
public String getDescription() {
return String.format(DESCRIPTION, getRelativePath());
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/FileExists.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/FileExists.java
index 5838d54a..f9d24693 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/FileExists.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/FileExists.java
@@ -16,6 +16,13 @@ public class FileExists extends SingleCondition {
private static final String DESCRIPTION = "Check if file or folder '%s' exists";
+ // Even though it is redundant to have this default constructor here, since it is
+ // the only one (the compiler would have added it implicitly), this is being explicitly
+ // set here to emphasize that the public default constructor should always be
+ // available by any transformation utility even when additional constructors are present.
+ // The reason for that is the fact that one or more of its properties might be set
+ // during transformation time, using the TransformationUtility set method
+ @SuppressWarnings("PMD.UnnecessaryConstructor")
public FileExists() {
}
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/AbstractTypeCheck.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/AbstractTypeCheck.java
index 7a3ee03b..77ef5343 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/AbstractTypeCheck.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/AbstractTypeCheck.java
@@ -90,6 +90,7 @@ public boolean eval(CompilationUnit compilationUnit) {
* 2- {@code typeSimpleName} is implicitly imported for being part of java.lang
* 3- {@code typeSimpleName} is at the same package where {@code compilationUnit} Java class is.
*/
+ @SuppressWarnings("PMD.SimplifyBooleanReturns")
private boolean isImported(CompilationUnit compilationUnit, String typeSimpleName) {
if (StringUtils.isBlank(typeSimpleName) || typeSimpleName.contains(".")) {
throw new IllegalArgumentException("Invalid type simple name");
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaCondition.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaCondition.java
index 86f83047..8a687216 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaCondition.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaCondition.java
@@ -34,6 +34,8 @@ public abstract class JavaCondition {
* the Java class to be evaluated
* @return the evaluation result including negation (if applicable)
*/
+ // This method's visibility is intentionally being set to package
+ @SuppressWarnings("PMD.DefaultPackage")
final boolean evaluate(CompilationUnit compilationUnit) {
boolean evalResult = eval(compilationUnit);
return negate ? !evalResult : evalResult;
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaMatch.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaMatch.java
index dc587049..428c2a10 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaMatch.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/conditions/java/JavaMatch.java
@@ -2,7 +2,6 @@
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
-import com.paypal.butterfly.extensions.api.ExecutionResult;
import com.paypal.butterfly.extensions.api.SingleCondition;
import com.paypal.butterfly.extensions.api.TUExecutionResult;
import com.paypal.butterfly.extensions.api.TransformationContext;
@@ -19,7 +18,8 @@
* based on a set of {@link JavaCondition}. It returns true only
* if they all are true. If the specified Java class file contains
* more than one type, only the outer one will be considered
- * during evaluation. If it has none, an error will be returned.
+ * during evaluation. If it has none, the evaluation will result
+ * in false and a warning be returned.
*
* @author facarvalho
*/
@@ -34,7 +34,8 @@ public class JavaMatch extends SingleCondition {
* based on a set of {@link JavaCondition}. It returns true only
* if they all are true. If the specified Java class file contains
* more than one type, only the outer one will be considered
- * during evaluation. If it has none, an error will be returned.
+ * during evaluation. If it has none, the evaluation will result
+ * in false and a warning be returned.
*/
public JavaMatch() {}
@@ -43,7 +44,8 @@ public JavaMatch() {}
* based on a set of {@link JavaCondition}. It returns true only
* if they all are true. If the specified Java class file contains
* more than one type, only the outer one will be considered
- * during evaluation. If it has none, an error will be returned.
+ * during evaluation. If it has none, the evaluation will result
+ * in false and a warning be returned.
*
* @param condition one condition to be evaluated. More can be added with
* {@link #addCondition(JavaCondition)}
@@ -95,7 +97,7 @@ public String getDescription() {
}
@Override
- protected ExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
+ protected TUExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
File javaClassFile = getAbsoluteFile(transformedAppFolder, transformationContext);
FileInputStream fileInputStream = null;
TUExecutionResult result = null;
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFile.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFile.java
index 00e3a67f..101df6a2 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFile.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFile.java
@@ -1,6 +1,5 @@
package com.paypal.butterfly.utilities.file;
-import com.paypal.butterfly.extensions.api.TOExecutionResult;
import com.paypal.butterfly.extensions.api.TUExecutionResult;
import com.paypal.butterfly.extensions.api.TransformationContext;
import com.paypal.butterfly.extensions.api.TransformationUtility;
@@ -8,7 +7,6 @@
import org.apache.commons.lang3.StringUtils;
import java.io.File;
-import java.io.FileNotFoundException;
import java.util.List;
/**
@@ -87,7 +85,7 @@ protected TUExecutionResult execution(File transformedAppFolder, TransformationC
File searchRootFolder = getAbsoluteFile(transformedAppFolder, transformationContext);
if (!searchRootFolder.exists()) {
- String details = String.format("No file named '%s' has been found by %s", fileName, getName());
+ String details = String.format("The specified search root folder does not exist");
if (failIfNotFound) {
TransformationUtilityException e = new TransformationUtilityException(details);
return TUExecutionResult.error(this, e);
diff --git a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFiles.java b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFiles.java
index d7ac6aca..8df82209 100644
--- a/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFiles.java
+++ b/butterfly-utilities/src/main/java/com/paypal/butterfly/utilities/file/FindFiles.java
@@ -1,12 +1,11 @@
package com.paypal.butterfly.utilities.file;
+import com.paypal.butterfly.extensions.api.TUExecutionResult;
import com.paypal.butterfly.extensions.api.TransformationContext;
import com.paypal.butterfly.extensions.api.TransformationUtility;
-import com.paypal.butterfly.extensions.api.TUExecutionResult;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.filefilter.AbstractFileFilter;
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.apache.commons.io.filefilter.*;
+import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
@@ -15,11 +14,16 @@
/**
* Finds files based on a regular expression
* against the file name and/or the file path. The search might be
- * recursive (including sub-folders) or not. If a file path regular
+ * recursive (searching also in sub-folders) or not. If a file path regular
* expression is set, then the search will be automatically recursive.
* If no file path regular expression is set, then the search
* is not recursive by default, but it may be set to as well.
*
+ * The term "file" here might refer to folders as well, and
+ * {@link #includeFiles} and {@link #includeFolders} can be used
+ * to specialize the search criteria in that regard. If none of them
+ * are explicitly set, only files will be searched.
+ *
* The root directory from where the search should take place
* can be defined by {@link #relative(String)},
* {@link #absolute(String)} or {@link #absolute(String, String)}.
@@ -34,23 +38,24 @@
*/
public class FindFiles extends TransformationUtility {
- private static final String DESCRIPTION = "Find files whose name and/or path match regular expression and are under folder %s%s";
+ private static final String DESCRIPTION = "Find files whose name and/or path match regular expression and are under %s%s";
private String nameRegex;
private String pathRegex;
private boolean recursive;
+ private boolean includeFiles = true;
+ private boolean includeFolders = false;
public FindFiles() {
}
/**
* Utility to find files based on a regular expression
- * against the file name and/or the file path. The search might be
- * recursive (including sub-folders) or not. If a file path regular
- * expression is set, then the search will be automatically and
- * necessarily recursive.
- * If no file path regular expression is set, then the search
- * is not recursive by default, but it may be set to as well.
+ * against the file name. The search might be
+ * recursive (searching also in sub-folders) or not.
+ *
+ * This search does not include folders, only files, unless
+ * {@link #setIncludeFolders(boolean)} is set to {@code true}.
*
* The root directory from where the search should take place
* can be defined by {@link #relative(String)},
@@ -69,12 +74,50 @@ public FindFiles(String nameRegex, boolean recursive) {
/**
* Utility to find files based on a regular expression
- * against the file name and/or the file path. The search might be
- * recursive (including sub-folders) or not. If a file path regular
+ * against the file name. The search might be
+ * recursive (searching also in sub-folders) or not.
+ *
+ * This search might include files only, folders only, or both,
+ * depending on how {@code includeFiles} and {@code includeFolders}
+ * are configured.
+ *
+ * The root directory from where the search should take place
+ * can be defined by {@link #relative(String)},
+ * {@link #absolute(String)} or {@link #absolute(String, String)}.
+ * If not set explicitly, then the search will happen from the root
+ * of the transformed application, which is equivalent to setting
+ * {@link #relative(String)} to {@code "."}
+ *
+ * @param nameRegex regular expression to be applied against file name during search
+ * @param recursive if true, sub-folders will also be searched
+ * @param includeFiles whether files should be included in the search or not
+ * @param includeFolders whether folders should be included in the search or not
+ */
+ public FindFiles(String nameRegex, boolean recursive, boolean includeFiles, boolean includeFolders) {
+ setNameRegex(nameRegex);
+ setRecursive(recursive);
+ setIncludeFiles(includeFiles);
+ setIncludeFolders(includeFolders);
+ }
+
+ /**
+ * Utility to find files based on a regular expression
+ * against the file name and the file path. Because a file path regular
* expression is set, then the search will be automatically and
* necessarily recursive.
- * If no file path regular expression is set, then the search
- * is not recursive by default, but it may be set to as well.
+ *
+ * Important notes:
+ *
+ *
Use forward slash as file separator. If the OS
+ * used during transformation execution uses another character
+ * as file separator, that will be automatically converted
+ * by this utility
+ *
Setting this to a non null value automatically sets
+ * recursive property to true
+ *
This regular expression will be evaluated against
+ * the file path starting from the search root
+ * directory
Transformation utility to fetch transformation context attributes post
+ transformation time, since they are always set
+ during transformation time.
+
+ An example of usage of this feature would be implementing
+ TransformationTemplate.getApplicationName(). The
+ application name mostly will only be known after the transformation
+ has began, but it might be necessary to know it outside of transformation
+ time (after it). For example, the metrics system needs to know it, as
+ seen in TransformationMetrics.getApplicationName().
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Returns the value of the transformation context attribute
+ specified earlier. If the attribute value is null, null is returned.
+ If this method is called prior to the execution of this transformation
+ utility, an IllegalStateException is thrown.
+
+
Returns:
+
the value of the transformation context attribute specified earlier
public abstract class DoubleCondition<T extends DoubleCondition>
+extends UtilityCondition<T>
+
Transformation utility condition to determine if a transformation utility
+ should be executed or not, based on a two files criteria. Every
+ DoubleUtilityCondition subclass result type must always
+ be boolean. The criteria to this type of condition
+ is based on two files (when comparing if two XML files are equal
+ for example). For conditions
+ based on evaluating a single file see SingleCondition.
+ For conditions based on multiple files see MultipleConditions
+
+ Important: it returns true if both files don't exist,
+ and it returns false if only one of them exists.
Condition to determine if a transformation utility
+ should be executed or not. Every
+ DoubleUtilityCondition subclass result type must always
+ be boolean. The criteria to this type of condition
+ is based on two files (when comparing if two XML files are equal
+ for example)
Condition to determine if a transformation utility
+ should be executed or not. Every
+ DoubleUtilityCondition subclass result type must always
+ be boolean. The criteria to this type of condition
+ is based on two files (when comparing if two XML files are equal
+ for example)
+
+
Parameters:
+
attribute - the name of the transformation context attribute
+ that refers to the file to be compared against the baseline file
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Set the exception associated with this result.
+ This exception can only be set if the result type allows it.
+ If that is not the case, an IllegalArgumentException
+ will be thrown
This method is used to notify subclasses that
+ the result type might have to change due to the
+ addition of a warning.
+
+ Usually it should change from a successful type to a
+ warning type. In case the result is an error kind of
+ type, then it should remain as is.
This is a convenience method in case the Extension subclass wants to implement its
+ automaticResolution(File) method based on one or more Maven pom files
Butterfly might be able to automatically identify, based on the application
+ content, the most applicable transformation template to transform it.
+ If no template applies to the application content, a TemplateResolutionException
+ is thrown explaining the reason why no template could be chosen.
+
+
Parameters:
+
applicationFolder - the folder where the code of the application to be transformed is
This is a convenience method in case the Extension subclass wants to implement its
+ automaticResolution(File) method based on one or more Maven pom files
+
+
Parameters:
+
folder - the folder where the pom.xml file would be
+
Returns:
+
the Model object related to the pom.xml file under folder, or null, if that file does
+ not exist, or any error happens when trying to read and parse it
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Creates a new single condition instance copying from this current
+ object, but setting the file it should perform against based
+ on the input parameters
Sets one or more transformation context attributes that hold list of Files
+ which the single condition should be evaluated against.
+ If more than one attribute is specified, all list of files will be
+ combined into a single one
+
+
Parameters:
+
filesAttributes - one or more transformation context attributes that hold list
+ of Files which the condition should be evaluated against
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Creates a new single condition instance copying from this current
+ object, but setting the file it should perform against based
+ on the input parameters
+
+
Parameters:
+
transformedAppFolder - the transformed application folder
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (MultipleConditions.Mode c : MultipleConditions.Mode.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
Transformation utility condition to determine if a transformation utility should be executed or not,
+ based on a multiple files criteria.
+ It performs condition instances based on a SingleCondition template against multiple files,
+ returning true if at least one file meets the condition (default mode).
+ There is an alternative mode where all files need to meet the
+ evaluation condition to result in true. For conditions
+ based on comparing two files see DoubleCondition.
+ For conditions based on evaluating a single file see SingleCondition
+
+ Note 1: if an evaluation against a specific file fails for any reason, then the
+ overall evaluation will be interrupted and result also in a failure.
+ Note 2: if the utility condition object (to be executed against the specified files)
+ has conditions, they will be ignored.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
public MultipleConditions(SingleCondition conditionTemplate)
+
Perform one transformation utility condition against multiple files,
+ returning true if at least one file meets the condition (default mode).
+ There is an alternative mode where all files need to meet the
+ evaluation condition to result in true. For conditions
+ based on comparing two files see DoubleCondition.
+ For conditions based on evaluating a single file see MultipleConditions
+
+
Parameters:
+
conditionTemplate - the utility condition template used to create conditions,
+ used to be evaluated against the list of files
Set the evaluation mode. The default mode is "at least one",
+ which means the result will be true if at least one file
+ meets the condition. The alternative mode is "all", which
+ requires all files to meet the evaluation condition to result
+ in true.
Sets one or more transformation context attributes that hold list of Files
+ which the condition should perform against.
+ If more than one attribute is specified, all list of files will be
+ combined into a single one.
+
+
Parameters:
+
filesAttributes - one or more transformation context attributes that hold list
+ of Files which the condition should perform
+ against
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
public class MultipleOperations
+extends TransformationUtility<MultipleOperations>
+implements com.paypal.butterfly.extensions.api.TransformationUtilityParent
+
Transformation utility to perform multiple transformation operations. Multiple transformation operations
+ are defined based on an operation template and two other factors, that could be applied
+ exclusively or together. They are:
+
+
Multiple files: multiple operations are defined based on multiple files specified as a
+ list, held as one or more transformation context attribute, and set via setFiles(String...)
+
Multiple configurations: multiple operations are defined based on different configurations,
+ set via setProperties(String, String)
+
+
+ In other words, there are two possible ways to define multiple operations: multiple
+ files, or multiple configurations (different property values). It is also possible
+ to combine both, resulting in multiple operations to be executed against multiple files and
+ with multiple configurations.
+
+ Important: when running against multiple files, any path set to this operation,
+ either relative or absolute, will be ignored, and set later at transformation time based on
+ the dynamically set multiple files. When running with multiple configurations, the properties set
+ during transformation time will override any value that could have been set during definition time
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Utility to perform multiple transformation operations. Multiple transformation operations
+ are defined based on an operation template and two other factors, that could be applied
+ exclusively or together. They are:
+
+
Multiple files: multiple operations are defined based on multiple files specified as a
+ list, held as one or more transformation context attribute, and set via setFiles(String...)
+
Multiple configurations: multiple operations are defined based on different configurations,
+ set via setProperties(String, String)
+
+
+ In other words, there are two possible ways to define multiple operations: multiple
+ files, or multiple configurations (different property values). It is also possible
+ to combine both, resulting in multiple operations to be executed against multiple files and
+ with multiple configurations.
+
+ Important: when running against multiple files, any path set to this operation,
+ either relative or absolute, will be ignored, and set later at transformation time based on
+ the dynamically set multiple files. When running with multiple configurations, the properties set
+ during transformation time will override any value that could have been set during definition time
Utility to perform multiple transformation operations. Multiple transformation operations
+ are defined based on an operation template and two other factors, that could be applied
+ exclusively or together. They are:
+
+
Multiple files: multiple operations are defined based on multiple files specified as a
+ list, held as one or more transformation context attribute, and set via setFiles(String...)
+
Multiple configurations: multiple operations are defined based on different configurations,
+ set via setProperties(String, String)
+
+
+ In other words, there are two possible ways to define multiple operations: multiple
+ files, or multiple configurations (different property values). It is also possible
+ to combine both, resulting in multiple operations to be executed against multiple files and
+ with multiple configurations.
+
+ Important: when running against multiple files, any path set to this operation,
+ either relative or absolute, will be ignored, and set later at transformation time based on
+ the dynamically set multiple files. When running with multiple configurations, the properties set
+ during transformation time will override any value that could have been set during definition time
+
+
Parameters:
+
templateOperation - a template of transformation operation to be performed
+ against all specified files
Sets one or more transformation context attributes that hold list of Files
+ which the transformation operations should perform against.
+ If more than one attribute is specified, all list of files will be
+ combined into a single one
+
+
Parameters:
+
filesAttributes - one or more transformation context attributes that hold list
+ of Files which the transformation operation should perform
+ against
This setter is similar to TransformationUtility.set(String, String), however it is more powerful, because
+ it allows setting, during transformation time, different properties values for each operation of a
+ MultipleOperations.
+
+ That being said, calling this method will only make a difference if this operation is executed as the
+ template operation for a multiple operations utility. That usually can be done by adding it to a
+ transformation template via TransformationTemplate.addMultiple(TransformationOperation, String...)
+
+
Parameters:
+
propertyName - the operation Java bean property name to be set during transformation time
+
propertyAttribute - the name of the transformation context attribute that holds a Set of
+ values to be each set individually (as the property value) to each operation of
+ a set of multiple operations. These values are set right before execution. If
+ the transformation context attribute value is not a Set, then a
+ TransformationUtilityException
+ will be thrown right before execution
Sets the template of transformation operation to be performed against all specified files.
+
+ Important: any path set to this operation, either relative
+ or absolute, will be ignored, and set later at transformation time based on
+ the dynamically set multiple files
+
+
Parameters:
+
templateOperation - the template of transformation operation to be performed against
+ all specified files
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
The TU failed, but not because of its utility execution itself, but because of an internal reason.
+ For example, when a TransformationUtilityException is thrown because the absolute file
+ the TU should execute against could not be resolved during transformation time.
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (PerformResult.Type c : PerformResult.Type.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
This means the utility has not been executed because one or more
+ of its dependencies "failed". See TransformationUtility.dependsOn(String...)
+ for the dependency failure criteria definition
This means The TU failed, but not because of its utility execution itself, but because of an internal reason.
+ For example, when a TransformationOperationException is thrown because the absolute file the TU should execute
+ against could not be resolved during transformation time
This means The TU failed, but not because of its utility execution itself, but because of an internal reason.
+ For example, when a TransformationOperationException is thrown because the absolute file the TU should execute
+ against could not be resolved during transformation time
This method is used to notify subclasses that
+ the result type might have to change due to the
+ addition of a warning.
+
+ Usually it should change from a successful type to a
+ warning type. In case the result is an error kind of
+ type, then it should remain as is.
Set the exception associated with this result.
+ This exception can only be set if the result type allows it.
+ If that is not the case, an IllegalArgumentException
+ will be thrown
public abstract class SingleCondition<T extends SingleCondition>
+extends UtilityCondition<T>
+
Transformation utility condition to determine if a transformation utility
+ should be executed or not, based on an one file criteria. Every
+ SingleUtilityCondition subclass result type must always
+ be boolean. The criteria to this type of condition
+ is based on evaluating a single file (when checking if a particular
+ file contains a given word for example). For conditions
+ based on comparing two files see DoubleCondition.
+ For conditions based on multiple files see MultipleConditions
No error happened, but for some reason the TO didn't apply any change. For example, when it was supposed to
+ delete lines in a text file based on a regular expression, but no lines were found to match the regular expression.
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (TOExecutionResult.Type c : TOExecutionResult.Type.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
This method is used to notify subclasses that
+ the result type might have to change due to the
+ addition of a warning.
+
+ Usually it should change from a successful type to a
+ warning type. In case the result is an error kind of
+ type, then it should remain as is.
Set the exception associated with this result.
+ This exception can only be set if the result type allows it.
+ If that is not the case, an IllegalArgumentException
+ will be thrown
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (TUExecutionResult.Type c : TUExecutionResult.Type.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
This method is used to notify subclasses that
+ the result type might have to change due to the
+ addition of a warning.
+
+ Usually it should change from a successful type to a
+ warning type. In case the result is an error kind of
+ type, then it should remain as is.
Set the exception associated with this result.
+ This exception can only be set if the result type allows it.
+ If that is not the case, an IllegalArgumentException
+ will be thrown
Holds meta-data information
+ to be shared among transformation utility objects,
+ allowing communication among them, and helping the
+ transformation process.
public abstract class TransformationOperation<T extends TransformationOperation>
+extends TransformationUtility<T>
+
Special type of TransformationUtility that applies a modification to the project.
+
+ Transformation operations are also known by TO.
+
+ Differences between a regular transformation utility (TU) and transformation operations (TO):
+
+
TU never modifies application. TO always does.
+
TU usually returns a value, but not necessarily. TO never does.
+
TU usually saves its result, but not necessarily. TO always does.
Sets whether or not the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object.
Sets whether or not the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object. See also TransformationUtility.isSaveResult().
saveResult - if the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object
Creates and returns a temporary read-only copy of the file to be modified.
+
+ The file to be modified by any transformation operation is set via
+ TransformationUtility.relative(String), TransformationUtility.absolute(String) or TransformationUtility.absolute(String, String)).
+ Some transformation operations though might need to read the file to be modified
+ as a stream, and modify it by writing to an output stream as that same file
+ is read. Since it is impossible to modify a file at the same time it is being read,
+ this utility method offers an convenient way to create a temporary read-only
+ copy of the file to be modified. This copy should be used to be read, while the original
+ file can be modified.
+
+ Important notes:
+
+
At the first time this method is called, the temporary file will be created and returned. If called again, the same temporary file created at the first time will be returned.
+
The read-only file will not reflect the changes performed in the original file at any moment, always keeping its original state.
+
There is no need to delete the temporary file after using it. Butterfly automatically deletes it when the JVM terminates.
+
+
+
Parameters:
+
transformedAppFolder - the folder where the transformed application code is
+
transformationContext - the transformation context object
+
Returns:
+
a temporary read-only copy of the file to be modified
+
Throws:
+
IOException - if the temporary file could not be created
Performs the transformation utility against
+ the application to be transformed
+
+ This is the one called by the transformation
+ engine, and regardless of any customization it
+ could have, it must always:
+
+
Adds a special transformation utility to perform multiple transformation operations against
+ multiple files specified as a list, held as a transformation context attribute
+
Adds a new transformation utility to the end of the list.
+ Also, if no name has been set for this utility yet, the template
+ names the utility based on this template's name and the order of
+ execution.
+
+ This method also register the template within the utility, which
+ means a transformation utility instance can be registered to
+ ONLY ONE transformation template
Adds a new transformation utility to the end of the list.
+ It sets the utility name before adding it though.
+
+ This method also register the template within the utility, which
+ means a transformation utility instance can be registered to
+ ONLY ONE transformation template
+
+
Parameters:
+
utility - the utility to be added
+
utilityName - the name to be set to the utility before adding it
Adds a special transformation utility to perform multiple transformation operations against
+ multiple files specified as a list, held as a transformation context attribute
+
+
+
Parameters:
+
templateOperation - a template of transformation operation to be performed
+ against all specified files
+
attributes - one or more transformation context attributes that hold list
+ of Files which the transformation operations should perform
+ against
Execute an utility in a loop while the value in TransformationContext attribute is true.
+ The defined is specified based on its name, specified in attribute.
+ If the attribute value is not a boolean, or if non-existent, it will be treated as false.
+
+
Parameters:
+
utility - the utility to be executed each iteration of the loop. To execute more than one, use a TransformationUtilityGroup
+
attribute - the name of the transformation context attribute to hold the loop condition
Execute an utility in a loop while the execution value resulted by condition is true.
+ The TransformationUtility object referenced by condition won't be saved to the TransformationContext,
+ it will be executed exclusively to the scope of this loop execution.
+ Any result other than a boolean true value, including failures, will be treated as false.
+
+
Parameters:
+
utility - the utility to be executed each iteration of the loop. To execute more than one, use a TransformationUtilityGroup
+
condition - the UtilityCondition object whose execution result will be used as the loop condition
This method has been deprecated. Use info(String, String...) instead.
+
+ Adds a new Log TU to the list.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
logMessage - the message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
public final void info(String infoMessage,
+ String... attributeNames)
+
Adds a new Log TU to the list,
+ setting its log level to INFO.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
infoMessage - the info message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
public final void debug(String debugMessage,
+ String... attributeNames)
+
Adds a new Log TU to the list,
+ setting its log level to DEBUG.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
debugMessage - the debug message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
public final void log(org.slf4j.event.Level logLevel,
+ String logMessage,
+ String... attributeNames)
+
Adds a new Log TU to the list.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
logLevel - the log level
+
logMessage - the message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
Returns the type of the transformed application,
+ Returns null if the application type is unknown.
+ This method is used mostly for meta-data purposes,
+ such as when providing transformation metrics.
Returns the name of the transformed application,
+ Returns null if the application name is unknown.
+ This method is used mostly for meta-data purposes,
+ such as when providing transformation metrics.
public abstract class TransformationUtility<T extends TransformationUtility>
+extends Object
+implements Cloneable
+
Gathers information about the project to be transformed without applying any modification on it.
+ It is the key element of Butterfly transformation engine. The result information is saved in the
+ TransformationContext object, to be used later by other transformation utilities.
+
+ Transformation utilities are executed against the to be transformed project,
+ based on the absolute project root folder defined in runtime, and a relative
+ path to a target file or folder, defined in compilation time.
+
+ Transformation utilities are also known by TU.
+
+ An example of a transformation operation utility would be to find recursively
+ a particular file based on its name and from a particular location (which would
+ be relative to the project root folder)
+
+ See TransformationOperation for a specialized transformation utility that
+ does modify the project
+
+ IMPORTANT:
+ Every TransformationUtility subclass MUST have a public no arguments default constructor,
+ and also public setters and getters for all properties they want to expose via set(String, String).
+ In addition to that, every setter must return the TransformationUtility instance.
Same as absolute(String, String), however, the absolute
+ file is set with an additional relative path, which is defined via parameter
+ additionalRelativePath.
Creates and returns a clone object identical to the original object,
+ except for the "has been performed" flag, which is set to false
+ in the clone object to be returned.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
This flag indicates whether the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object.
Performs the transformation utility against
+ the application to be transformed
+
+ This is the one called by the transformation
+ engine, and regardless of any customization it
+ could have, it must always:
+
+ 1- Call applyPropertiesFromContext(TransformationContext)
+ 2- Call execution(File, TransformationContext)
+
+
+ This method is NOT supposed to be overwritten,
+ unless you really know what you are doing.
Sets whether or not the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object.
public T setContextAttributeName(String contextAttributeName)
+
Set the name to be used as key for the result of this utility
+ when saved into the transformation context.
+ If this is not set, or null, then the utility name will be used instead
+
+
Parameters:
+
contextAttributeName - the name to be used as key for the result of this utility
+ when saved into the transformation context.
Return the name to be used as key for the result of this utility
+ when saved into the transformation context.
+ If it is null, then the utility name will be used instead
+
+
Returns:
+
the name to be used as key for the result of this utility
+ when saved into the transformation context
public final T setParent(com.paypal.butterfly.extensions.api.TransformationUtilityParent parent,
+ int order)
+
Register this utility to its parent, and also assign it a name
+ based on the parent name and order of execution.
+
+ Usually the parent is a TransformationTemplate
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
+
+
Returns:
+
a short one line, but specific, description about the transformation
+ utility
Sets the relative path from the application root folder
+ to the file or folder the transformation utility should perform against.
+ The path separator is automatically normalized, so there are three valid
+ options when separating folders in the path:
+
+
Two backward slashes (e.g. relative("myFolder\\file.txt")
+
+ The slashes are replaced by OS specific separator char in runtime.
+
+ The default value is ".". which means the root of the transformed application
+
+
Parameters:
+
relativePath - from the application root folder
+ to the file or folder the transformation utility should be performed against
public static String getRelativePath(File baselineFile,
+ File targetFile)
+
Returns a relative path from baselineFile to targetFile.
+ The file separator used is specific to the current OS. If the baseline file
+ is not entirely within the path to target file, then the target file
+ absolute path is returned
+
+
Parameters:
+
baselineFile - the file whose returned relative path should start from.
+ It must be aa direct or indirect parent file to targetFile
+
targetFile - the file whose returned relative path should take to
public final T set(String propertyName,
+ String contextAttributeName)
+
This method allows setting properties in this transformation
+ utility during transformation time, right before its execution.
+ This is very useful when the property value is not known during
+ transformation definition. Any attribute stored in the
+ transformation context can be used as the value to be set to the
+ property. In most of the cases the result of a prior
+ transformation utility is used as property value.
+ Notice that, because this feature relies on reflection, it is not
+ cheap, especially because it happens during transformation time.
+ So, use it only when really necessary.
+
+
Parameters:
+
propertyName - the transformation utility Java property name
+
contextAttributeName - the name of the transformation context attribute whose
+ value will be set as the property value right before
+ execution
Applies transformation utility properties during transformation time, but
+ prior to execution (right before it). The properties values are gotten from
+ the transformation context object.
+
+
Parameters:
+
transformationContext - the transformation context object
There are two ways to specify the file, or folder, the transformation
+ utility is suppose to perform against. The default and most commons one is
+ by setting the relative path to it, which is done usually via the constructor
+ or relative(String)). That should be the chosen option whenever
+ the relative location is known during transformation template definition time.
+
+ However, sometimes that is not possible because that location will only be known
+ during transformation time. In cases like this, usually another utility is used to
+ find that location first, and then save it as transformation context attribute. In
+ this case, this setter here can be used to set the absolute file location based
+ on such context attribute. Whenever this is set, the relative path attribute is
+ ignored.
+
+ See also getAbsoluteFile(File, TransformationContext), relative(String)
+ and getRelativePath()
+
+
Parameters:
+
contextAttributeName - the name of the transformation context attribute whose
+ value will be set as the absolute file right before
+ execution
public T absolute(String contextAttributeName,
+ String additionalRelativePath)
+
Same as absolute(String, String), however, the absolute
+ file is set with an additional relative path, which is defined via parameter
+ additionalRelativePath. This method is powerful because it allows setting
+ the absolute file using a portion of the location (absolute) that is only known during
+ transformation time, plus also a second portion of the location (relative) that is
+ already known during definition time
+
+ See also getAbsoluteFile(File, TransformationContext), relative(String)
+ and getRelativePath()
+
+
Parameters:
+
contextAttributeName - the name of the transformation context attribute whose
+ value will be set as the absolute file right before
+ execution
+
additionalRelativePath - an additional relative path to be added to the absolute
+ file coming from the transformation context. The path
+ separator will be normalized, similar to what happens
+ in relative(String)
Performs the transformation utility against
+ the application to be transformed
+
+ This is the one called by the transformation
+ engine, and regardless of any customization it
+ could have, it must always:
+
+
If set to true, abort the whole transformation if validation or execution fails.
+ If not, just state a warning, aborts the operation execution only.
+ Notice that abortion here means interrupting the transformation.
+ It does not mean rolling back the changes that have might already been done
+ by this transformation operation by the time it failed
+
+
Parameters:
+
abort - if set to true, abort the whole transformation if validation or execution fails.
+ If not, just state a warning, aborts the operation execution only
public final T abortOnFailure(boolean abort,
+ String abortionMessage)
+
If set to true, abort the whole transformation if validation or execution fails.
+ If not, just state a warning, aborts the operation execution only.
+ Notice that abortion here means interrupting the transformation.
+ It does not mean rolling back the changes that have might already been done
+ by this transformation operation by the time it failed
+
+
Parameters:
+
abort - if set to true, abort the whole transformation if validation or execution fails.
+ If not, just state a warning, aborts the operation execution only
+
abortionMessage - a message to be logged if a fail happens and transformation
+ has to be aborted
Returns whether this operation aborts the transformation or not in
+ case of an operation failure. Notice that this method does NOT
+ change the state this object in any ways, it is just a getter.
+
+
Returns:
+
true only if this operation aborts the transformation or not in
+ case of an operation failure
This flag indicates whether the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object.
+
+ In most cases it should do so, because that is the main purpose of
+ every transformation utility, to produce and share useful data with other
+ transformation utilities and operations.
+
+ However, there are rare cases,
+ for example Log,
+ where no value will be produced and nothing should be saved to the
+ transformation context attribute
+
+
Returns:
+
true only if the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object
Sets whether or not the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object. See also isSaveResult().
+
+
Parameters:
+
saveResult - if the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object
Add all transformation utilities this utility depends on.
+ Notice that this is not cumulative, meaning if this method has been called previously,
+ that dependencies set will be entirely replaced by this new one.
+
+ This notion of "dependency" among TUs help resilience in two ways:
+
+
If TU B depends on TU A, and if TU A "fails"
+ but doesn't abort transformation, then TU B would be skipped
+
If TU B depends on TU A, then that means TU A is necessarily supposed to be executed first,
+ if not, TU B will be skipped
+
+ The term "fails" in this context means the perform result is of one of these types:
+
+
+
+ A dependency failure is also possible if perform result type is PerformResult.Type.EXECUTION_RESULT,
+ and the execution result type is one of the following:
+
+
Check if any of dependency of this TU failed. If that is true,
+ returns a result object stating so. If not, returns null. If this TU
+ has no dependencies it also returns null. See dependsOn(String...)
+ to find out the dependency failure criteria
+
+
Parameters:
+
transformationContext - the transformation context object, in this case used
+ to check all past executed utilities
+
Returns:
+
a result object if any of dependency of this utility failed,
+ or null, if that is not the case, or if this utility does not have dependencies
public final T executeIf(String conditionAttributeName)
+
When set, this TU will only execute if this transformation context
+ attribute is existent and true. In other words, it will execute if
+ not null and, if of Boolean type, true
+
+
Parameters:
+
conditionAttributeName - the name of the transformation context attribute which
+ holds a boolean value used to evaluate if this
+ utility should be executed or not
When set, this TU will only execute if this utilityCondition object,
+ executed right before this TU, result in true.
+
+ Differences between this approach and executeIf(String):
+
+
Instead of relying on a TCA (attribute) with the condition result, this method is based on the direct execution of the UtilityCondition object
+
The UtilityCondition object is always executed necessarily against the same file set in the transformation utility it is being used. Because of that, any value set in the condition itself via relative(String) or absolute(String) is ignored.
+
The UtilityCondition object does not produce any TCA, neither its result value or result object. Instead, it hands its result directly to the TU, so that the condition can be evaluated just before the TU executes (or not, if it fails).
public final T executeUnless(String conditionAttributeName)
+
When set, this TU will execute, unless this transformation context
+ attribute is existent and true. In other words, it will execute, unless if
+ not null and, if of Boolean type, true
+
+
Parameters:
+
conditionAttributeName - the name of the transformation context attribute which
+ holds a boolean value used to evaluate if this
+ utility should be executed or not
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
+
+
Parameters:
+
transformedAppFolder - the folder where the transformed application code is
+
transformationContext - the transformation context object
+
Returns:
+
an object with the result of this execution, to be better defined
+ by the concrete utility class, since its type is generic
Return true only if a file has been set explicitly either via relative(String) or absolute(String).
+ If set via relative(String) it will only return true if set to anything other than "", which would mean the root of the application.
Creates and returns a clone object identical to the original object,
+ except for the "has been performed" flag, which is set to false
+ in the clone object to be returned. See hasBeenPerformed().
Check if value is a blank String, if it is, then a
+ TransformationDefinitionException is thrown.
+
+ This check is used for mandatory properties where value cannot be null
+ neither an empty string.
Check if value is an empty String, if it is, then a
+ TransformationDefinitionException is thrown.
+
+ This check is used for optional properties where value can be null,
+ but not an empty string.
Check if value is null, if it is, then a
+ TransformationDefinitionException is thrown.
+
+ This check is used for mandatory non-String properties,
+ where value cannot be null
Compare this instance against the specified object, and return
+ true only if they are equal. Notice though that the fact that
+ the utility has been performed or not will NOT be used for this
+ comparison.
Group of transformation utilities. The benefit of grouping them is the ability to, for example, condition the execution of all of them
+ together (by setting TransformationUtility.executeIf(String) to the group), or to loop them, etc.
Adds a special transformation utility to perform multiple transformation operations against
+ multiple files specified as a list, held as a transformation context attribute
+
Creates and returns a clone object identical to the original object,
+ except for the "has been performed" flag, which is set to false
+ in the clone object to be returned.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
Adds a special transformation utility to perform multiple transformation operations against
+ multiple files specified as a list, held as a transformation context attribute
+
+
+
Parameters:
+
templateOperation - a template of transformation operation to be performed
+ against all specified files
+
attributes - one or more transformation context attributes that hold list
+ of Files which the transformation operations should perform
+ against
+
Returns:
+
the name of the special transformation utility that performs multiple transformation operations
This method has been deprecated. Use info(String, String...) instead.
+
+ Adds a new Log TU to the list.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
logMessage - the message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
public final void info(String infoMessage,
+ String... attributeNames)
+
Adds a new Log TU to the list,
+ setting its log level to INFO.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
infoMessage - the info message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
public final void debug(String debugMessage,
+ String... attributeNames)
+
Adds a new Log TU to the list,
+ setting its log level to DEBUG.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
debugMessage - the debug message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
public final void log(org.slf4j.event.Level logLevel,
+ String logMessage,
+ String... attributeNames)
+
Adds a new Log TU to the list.
+ The log messages may contain placeholders to be replaced by transformation context
+ attribute values. Use {} as placeholder marker.
+
+
Parameters:
+
logLevel - the log level
+
logMessage - the message to be logged, containing {} placeholders to be replaced by
+ transformation context attribute values
+
attributeNames - an array of names of transformation context attributes, whose values
+ are going to be used in the log message
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Creates and returns a clone object identical to the original object,
+ except for the "has been performed" flag, which is set to false
+ in the clone object to be returned. See TransformationUtility.hasBeenPerformed().
Allows the execution of any transformation utility instance,
+ including a TransformationUtilityGroup, multiple times in a loop.
+ The number of iterations is defined by one of these options:
+
+
Specifying the number of iterations.
+
Specifying a TransformationContext attribute (by its name) whose value is true or false. If that is not a boolean, or if non-existent, it will be treated as false. If that is false, the loop is interrupted.
+
Specifying a UtilityCondition object whose result is true or false. The result of this TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false. If that is false, the loop is interrupted.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
In this case the condition to execute the next iteration is based on
+ a TransformationContext attribute (specified by its name) whose
+ value is true or false.
Allows the execution of any transformation utility instance,
+ including a TransformationUtilityGroup, multiple times in a loop.
+ The number of iterations is defined by one of these options:
+
+
Specifying the number of iterations.
+
Specifying a TransformationContext attribute (by its name) whose value is true or false. If that is not a boolean, or if non-existent, it will be treated as false. If that is false, the loop is interrupted.
+
Specifying a UtilityCondition object whose result is true or false. The result of this TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false. If that is false, the loop is interrupted.
Allows the execution of any transformation utility instance,
+ including a TransformationUtilityGroup, multiple times in a loop.
+ The number of iterations is defined by one of these options:
+
+
Specifying the number of iterations.
+
Specifying a TransformationContext attribute (by its name) whose value is true or false. If that is not a boolean, or if non-existent, it will be treated as false. If that is false, the loop is interrupted.
+
Specifying a UtilityCondition object whose result is true or false. The result of this TU condition object won't be saved to the TC, it will be executed exclusively to the scope of this loop execution. Any result other than a boolean true value, including failures, will be treated as false. If that is false, the loop is interrupted.
+
+
+
Parameters:
+
template - the transformation utility instance to be used a template.
+ A clone utility instance will be created out of the template
+ for each iteration. See TransformationUtility.clone() for further information
+ about the clone object.
Sets the transformation utility instance to be used as a template.
+ A clone utility instance will be created out of the template
+ for each iteration. See TransformationUtility.clone() for further information
+ about the clone object.
+
+
Parameters:
+
template - the transformation utility instance to be used as template.
In this case the condition to execute the next iteration is based on
+ a pre-defined number of iterations to be executed. Each execution
+ decrease the remaining number of iterations.
+
+
Parameters:
+
iterations - the total number of iterations to be executed
In this case the condition to execute the next iteration is based on
+ a TransformationContext attribute (specified by its name) whose
+ value is true or false. If that is not a boolean, or if non-existent,
+ it will be treated as false. If that is false, the loop is interrupted.
+
+
Parameters:
+
attribute - the name of the transformation context attribute
+ holding the boolean to be used as the condition
+ to execute the next iteration. If that is false,
+ the loop is interrupted.
In this case the condition to execute the next iteration is based on
+ a UtilityCondition object whose result is true or false.
+ The result of this TU condition object won't be saved to the TC,
+ it will be executed exclusively to the scope of this loop execution.
+ Any result other than a boolean true value, including failures, will be treated as false.
+ If that is false, the loop is interrupted.
+
+
Parameters:
+
condition - the UtilityCondition object whose result
+ will be used as the condition to execute the next iteration.
+ If that is false, the loop is interrupted.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
public abstract class UtilityCondition<U extends UtilityCondition>
+extends TransformationUtility<U>
+
Condition to determine if a transformation utility
+ should be executed or not. Although this type has no
+ explicitly defined structural additions to typical
+ TransformationUtility classes, every
+ UtilityCondition subclass result type must always
+ be boolean. The criteria to the condition can be
+ based on a single file (when checking if a particular
+ file contains a given word for example) or multiple files
+ (when comparing two files for example).
+
+ IMPORTANT:
+ Every UtilityCondition subclass MUST be a Java bean, which means they must have
+ a public no arguments default constructor, and also public setters and getters for all
+ their properties. In addition to that, every setter must return the
+ UtilityCondition instance.
Creates a new single condition instance copying from this current
+ object, but setting the file it should perform against based
+ on the input parameters
Adds a special transformation utility to perform multiple transformation operations against
+ multiple files specified as a list, held as a transformation context attribute
+
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by adding elements to it,
+ standardizing the behavior and API if the element to be added already exists.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by changing or modify elements,
+ standardizing the behavior and API in the absence of the element to be manipulated.
Registers a manual instruction, also known as "post-upgrade instruction", which can be seen as
+ a transformation operation that is too complex to be automated, but that should at least be recognized and reported by Butterfly.
Obtains a specific entry from a Map object stored in the TransformationContext,
+ and store its value as a new attribute in the transformation context.
In this case the condition to execute the next iteration is based on
+ a TransformationContext attribute (specified by its name) whose
+ value is true or false.
Thrown whenever an unexpected behavior or result
+ during execution of a TransformationUtility.
+ Transformation utility exceptions ALWAYS abort the transformation process.
Possible behaviors in case the element to be added already exists.
+ Each of these options is related to instances of TOExecutionResult.Type,
+ although they are intentionally not supposed to match necessarily one-to-one.
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (AddElement.IfPresent c : AddElement.IfPresent.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by adding elements to it,
+ standardizing the behavior and API if the element to be added already exists.
+
+
+ Examples:
+
Convenience class with AddElement implementation ready for TransformationOperation subclasses.
+ Protected instance variable ifPresent can be used when deciding the result type,
+ in case the element to be added is already present.
Possible behaviors in case the element to be changed or removed is not present.
+ Each of these options is related to instances of TOExecutionResult.Type,
+ although they are intentionally not supposed to match necessarily one-to-one.
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (ChangeOrRemoveElement.IfNotPresent c : ChangeOrRemoveElement.IfNotPresent.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by changing or modify elements,
+ standardizing the behavior and API in the absence of the element to be manipulated.
+
+
+ Examples:
+
Convenience class with ChangeOrRemoveElement implementation ready for TransformationOperation subclasses.
+ Protected instance variable ifNotPresent can be used when deciding the result type,
+ in case the element to be changed or removed is not present.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by adding elements to it,
+ standardizing the behavior and API if the element to be added already exists.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by changing or modify elements,
+ standardizing the behavior and API in the absence of the element to be manipulated.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by adding elements to it,
+ standardizing the behavior and API if the element to be added already exists.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by changing or modify elements,
+ standardizing the behavior and API in the absence of the element to be manipulated.
Holds meta-data information
+ to be shared among transformation utility objects,
+ allowing communication among them, and helping the
+ transformation process.
Holds meta-data information
+ to be shared among transformation utility objects,
+ allowing communication among them, and helping the
+ transformation process.
Holds meta-data information
+ to be shared among transformation utility objects,
+ allowing communication among them, and helping the
+ transformation process.
Returns the current version of the application, in other words, the
+ version the application would be upgraded from when this upgrade
+ template is executed
Returns the current version of the application, in other words, the
+ version the application would be upgraded from when this upgrade
+ template is executed
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Provides logging statements during transformation time.
+ Since all it does is logging, it always returns TUExecutionResult.Type.NULL as result of
+ execution.
+
+ If no log level is defined, then it will be set to INFO, except
+ when there is only one attribute and it is null. In this case
+ it will be set to WARNING.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Registers a manual instruction, also known as "post-upgrade instruction", which can be seen as
+ a transformation operation that is too complex to be automated, but that should at least be recognized and reported by Butterfly.
+
+ In the end of the transformation, every manual instruction is reported in order of registration as Markdown (.md) files.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Obtains a specific entry from a Map object stored in the TransformationContext,
+ and store its value as a new attribute in the transformation context. The name of the transformation
+ context attribute that holds the map object, and the key used to get the map entry, have to be specified.
+
+ The new attribute saved into the transformation context is named based on the utility name, unless
+ TransformationUtility.setContextAttributeName(String) is called, as usual, nothing new here.
This utility obtains a specific entry from a Map object stored in the transformation context,
+ and store its value as a new attribute in the transformation context.
This utility obtains a specific entry from a Map object stored in the transformation context,
+ and store its value as a new attribute in the transformation context.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
This utility obtains a specific entry from a Map object stored in the transformation context,
+ and store its value as a new attribute in the transformation context. The name of the transformation
+ context attribute that holds the map object, and the key used to get the map entry, have to be specified.
+
+ The new attribute saved into the transformation context is named based on the utility name, unless
+ TransformationUtility.setContextAttributeName(String) is called, as usual, nothing new here.
This utility obtains a specific entry from a Map object stored in the transformation context,
+ and store its value as a new attribute in the transformation context. The name of the transformation
+ context attribute that holds the map object, and the key used to get the map entry, have to be specified.
+
+ The new attribute saved into the transformation context is named based on the utility name, unless
+ TransformationUtility.setContextAttributeName(String) is called, as usual, nothing new here.
+
+
Parameters:
+
mapName - the name of the transformation context attribute that holds the map object
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Checks the perform result, and optionally execution result as well, of a TransformationUtility instance.
+ If a result for the specified utility name is not found, this condition returns false, but with a warning.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated. This is supposed to be an one line statement about the
+ specific transformation utility that was executed. This would be used for example in
+ log statements or user interfaces.
The implementation execution of this transformation utility.
+ The returned object is the result of the execution and is always
+ automatically saved in the transformation context as a new
+ attribute (whose key is the name of the transformation utility), unless
+ TransformationUtility.isSaveResult() returns false.
+
+ Important: this method MUST NEVER return null, and it must catch its executions exceptions
+ and wrap them into a ExecutionResult error object.
Registers a manual instruction, also known as "post-upgrade instruction", which can be seen as
+ a transformation operation that is too complex to be automated, but that should at least be recognized and reported by Butterfly.
Obtains a specific entry from a Map object stored in the TransformationContext,
+ and store its value as a new attribute in the transformation context.
Registers a manual instruction, also known as "post-upgrade instruction", which can be seen as
+ a transformation operation that is too complex to be automated, but that should at least be recognized and reported by Butterfly.
Obtains a specific entry from a Map object stored in the TransformationContext,
+ and store its value as a new attribute in the transformation context.
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Use
+
Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by adding elements to it,
+ standardizing the behavior and API if the element to be added already exists.
Adds a special transformation utility to perform multiple transformation operations against
+ multiple files specified as a list, held as a transformation context attribute
+
This interface should be implemented by TransformationOperation
+ subclasses that intend to modify a project by changing or modify elements,
+ standardizing the behavior and API in the absence of the element to be manipulated.
Creates and returns a clone object identical to the original object,
+ except for the "has been performed" flag, which is set to false
+ in the clone object to be returned.
Returns a short one line, but SPECIFIC, description about the transformation
+ utility, including mentioning the files and/or folders
+ to be manipulated.
This is a convenience method in case the Extension subclass wants to implement its
+ Extension.automaticResolution(File) method based on one or more Maven pom files
This flag indicates whether the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object.
Registers a manual instruction, also known as "post-upgrade instruction", which can be seen as
+ a transformation operation that is too complex to be automated, but that should at least be recognized and reported by Butterfly.
Obtains a specific entry from a Map object stored in the TransformationContext,
+ and store its value as a new attribute in the transformation context.
+
+
MapValue() - Constructor for class com.paypal.butterfly.extensions.api.utilities.MapValue
+
+
This utility obtains a specific entry from a Map object stored in the transformation context,
+ and store its value as a new attribute in the transformation context.
This utility obtains a specific entry from a Map object stored in the transformation context,
+ and store its value as a new attribute in the transformation context.
Creates a new single condition instance copying from this current
+ object, but setting the file it should perform against based
+ on the input parameters
In this case the condition to execute the next iteration is based on
+ a TransformationContext attribute (specified by its name) whose
+ value is true or false.
Sets whether or not the value produced by the transformation utility execution,
+ and also its result object as a whole, should both be saved in the transformation
+ context object.
Holds meta-data information
+ to be shared among transformation utility objects,
+ allowing communication among them, and helping the
+ transformation process.
public class CompareFiles
+extends com.paypal.butterfly.extensions.api.DoubleCondition<CompareFiles>
+
Compares two files and returns true if the content of the files are equal,
+ or if they both don't exist. Returns false otherwise.
+
+ See DoubleCondition to find out how to set the baseline and the comparison files
Compares two files and returns true if the content of the files are equal,
+ or if they both don't exist. Returns false otherwise.
+
+ See DoubleCondition to find out how to set the baseline and the comparison files
Compares two files and returns true if the content of the files are equal,
+ or if they both don't exist. Returns false otherwise.
+
+ See DoubleCondition to find out how to set the baseline and the comparison files
+
+
Parameters:
+
attribute - the name of the transformation context attribute
+ that refers to the file to be compared against the baseline file
public class CompareXMLFiles
+extends com.paypal.butterfly.extensions.api.DoubleCondition<CompareXMLFiles>
+
Compares two XML files and returns true if their contents are equal,
+ or if both files don't exist. Returns false otherwise.
+ Attribute orders, comments and white spaces are ignored during the comparison.
+ It results in error if any of the two files is not a well formed XML file.
+
+ See DoubleCondition
+ to find out how to set the baseline and the comparison files
Compares two XML files and returns true if their contents are equal,
+ or if both files don't exist. Returns false otherwise.
+ Attribute orders, comments and white spaces are ignored during the comparison.
+ It results in error if any of the two files is not a well formed XML file.
+
+ See DoubleCondition
+ to find out how to set the baseline and the comparison files
Compares two XML files and returns true if their contents are equal,
+ or if both files don't exist. Returns false otherwise.
+ Attribute orders, comments and white spaces are ignored during the comparison.
+ It results in error if any of the two files is not a well formed XML file.
+
+ See DoubleCondition
+ to find out how to set the baseline and the comparison files
+
+
Parameters:
+
attribute - the name of the transformation context attribute
+ that refers to the file to be compared against the baseline file
public class RegexMatch
+extends com.paypal.butterfly.extensions.api.SingleCondition<RegexMatch>
+
Checks if a regular expression matches any line in the specified text file.
+ It returns true only if the specified text file has one or more lines that match
+ the given regular expression.
Evaluates this condition against the specified compilation
+ unit and returns the evaluation result. This implementation
+ must ignore the negate property during this evaluation.
+ The negation behavior will be considered in JavaCondition.evaluate(CompilationUnit)
Evaluates this condition against the specified compilation
+ unit and returns the evaluation result. This implementation
+ must ignore the negate property during this evaluation.
+ The negation behavior will be considered in evaluate(CompilationUnit)
+
+
Parameters:
+
compilationUnit - the CompilationUnit that represents
+ the Java class to be evaluated
Sets whether the result should be negated, meaning,
+ resulting true whenever its evaluation result would
+ normally results false, and vice-versa. The default
+ value is false.
public class JavaMatch
+extends com.paypal.butterfly.extensions.api.SingleCondition<JavaMatch>
+
Parses and evaluates the specified Java class file
+ based on a set of JavaCondition. It returns true only
+ if they all are true. If the specified Java class file contains
+ more than one type, only the outer one will be considered
+ during evaluation. If it has none, the evaluation will result
+ in false and a warning be returned.
This utility parses and evaluates the specified Java class file
+ based on a set of JavaCondition. It returns true only
+ if they all are true. If the specified Java class file contains
+ more than one type, only the outer one will be considered
+ during evaluation. If it has none, the evaluation will result
+ in false and a warning be returned.
This utility parses and evaluates the specified Java class file
+ based on a set of JavaCondition. It returns true only
+ if they all are true. If the specified Java class file contains
+ more than one type, only the outer one will be considered
+ during evaluation. If it has none, the evaluation will result
+ in false and a warning be returned.
Multiple transformation utility conditions, organized by type, each one having its own subpackage.
+ Transformation utility conditions are used to determine if a specific transformation utility
+ should be executed or not. Transformation utility condition is a special type of transformation utility that
+ always result in a boolean. The criteria to its condition can be based on a single file (when checking if a particular
+ file contains a given word for example) or multiple files (when comparing two files for example).
public class FindFile
+extends com.paypal.butterfly.extensions.api.TransformationUtility<FindFile>
+
Finds a file based on its name. The search is
+ always recursive (includes sub-folders). If no file is
+ found, null is returned, unless failIfNotFound(boolean) is set to true.
+ If multiple files are found, an error is returned.
+
+ The root directory from where the search should take place
+ can be defined by TransformationUtility.relative(String),
+ TransformationUtility.absolute(String) or TransformationUtility.absolute(String, String).
+ If not set explicitly, then the search will happen from the root
+ of the transformed application, which is equivalent to setting
+ TransformationUtility.relative(String) to "."
+
+ If no file is found, a TUExecutionResult.Type.NULL
+ is returned, unless failIfNotFound(boolean) is set to true
+
+ See FindFiles for a better refined search and to find multiple files.
public class FindFiles
+extends com.paypal.butterfly.extensions.api.TransformationUtility<FindFiles>
+
Finds files based on a regular expression
+ against the file name and/or the file path. The search might be
+ recursive (searching also in sub-folders) or not. If a file path regular
+ expression is set, then the search will be automatically recursive.
+ If no file path regular expression is set, then the search
+ is not recursive by default, but it may be set to as well.
+
+ The term "file" here might refer to folders as well, and
+ includeFiles and includeFolders can be used
+ to specialize the search criteria in that regard. If none of them
+ are explicitly set, only files will be searched.
+
+ The root directory from where the search should take place
+ can be defined by TransformationUtility.relative(String),
+ TransformationUtility.absolute(String) or TransformationUtility.absolute(String, String).
+ If not set explicitly, then the search will happen from the root
+ of the transformed application, which is equivalent to setting
+ TransformationUtility.relative(String) to "."
+
+ If no files have been found, an empty list is returned and a
+ warning is stated in the result
public FindFiles(String nameRegex,
+ boolean recursive)
+
Utility to find files based on a regular expression
+ against the file name. The search might be
+ recursive (searching also in sub-folders) or not.
+
+ This search does not include folders, only files, unless
+ setIncludeFolders(boolean) is set to true.
+
+ The root directory from where the search should take place
+ can be defined by TransformationUtility.relative(String),
+ TransformationUtility.absolute(String) or TransformationUtility.absolute(String, String).
+ If not set explicitly, then the search will happen from the root
+ of the transformed application, which is equivalent to setting
+ TransformationUtility.relative(String) to "."
+
+
Parameters:
+
nameRegex - regular expression to be applied against file name during search
+
recursive - if true, sub-folders will also be searched
Utility to find files based on a regular expression
+ against the file name. The search might be
+ recursive (searching also in sub-folders) or not.
+
+ This search might include files only, folders only, or both,
+ depending on how includeFiles and includeFolders
+ are configured.
+
+ The root directory from where the search should take place
+ can be defined by TransformationUtility.relative(String),
+ TransformationUtility.absolute(String) or TransformationUtility.absolute(String, String).
+ If not set explicitly, then the search will happen from the root
+ of the transformed application, which is equivalent to setting
+ TransformationUtility.relative(String) to "."
+
+
Parameters:
+
nameRegex - regular expression to be applied against file name during search
+
recursive - if true, sub-folders will also be searched
+
includeFiles - whether files should be included in the search or not
+
includeFolders - whether folders should be included in the search or not
public FindFiles(String nameRegex,
+ String pathRegex)
+
Utility to find files based on a regular expression
+ against the file name and the file path. Because a file path regular
+ expression is set, then the search will be automatically and
+ necessarily recursive.
+
+ Important notes:
+
+
Use forward slash as file separator. If the OS
+ used during transformation execution uses another character
+ as file separator, that will be automatically converted
+ by this utility
+
Setting this to a non null value automatically sets
+ recursive property to true
+
This regular expression will be evaluated against
+ the file path starting from the search root
+ directory
+
+
+ The root directory from where the search should take place
+ can be defined by TransformationUtility.relative(String),
+ TransformationUtility.absolute(String) or TransformationUtility.absolute(String, String).
+ If not set explicitly, then the search will happen from the root
+ of the transformed application, which is equivalent to setting
+ TransformationUtility.relative(String) to "."
+
+
Parameters:
+
nameRegex - regular expression to be applied against file name during search
+
pathRegex - regular expression to be applied against file path during search
Set regular expression to be used to match the file path
+ during the search
+ Important notes:
+
+
Use forward slash as file separator. If the OS
+ used during transformation execution uses another character
+ as file separator, that will be automatically converted
+ by this utility
+
Setting this to a non null value automatically sets
+ recursive property to true
+
This regular expression will be evaluated against
+ the file path starting from the search root
+ directory
+
+
+
Parameters:
+
pathRegex - regular expression to be used to match the file path
+ during the search
Set whether the search should be recursive or not.
+ If a file path regular expression has been set,
+ then this property will be automatically set to
+ true.
+ Important: setting this to false automatically sets
+ the file path regular expression to null
+
+
Parameters:
+
recursive - whether the search should be recursive
public class LoadFile
+extends com.paypal.butterfly.extensions.api.TransformationUtility<LoadFile>
+
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context. The file is written to a temporary folder to be defined by the OS.
+ If no resource file is found, an error is returned.
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context. The file is written to a temporary folder to be defined by the OS.
+ If no resource file is found, an error is returned.
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context. The file is written to a temporary folder to be defined by the OS.
+ If no resource file is found, an error is returned.
+
+
Parameters:
+
resource - the name of the resource in the classpath
public class LocateFile
+extends com.paypal.butterfly.extensions.api.TransformationUtility<LocateFile>
+
Locates a file based on the relative or absolute
+ location specified. It does not find files, it just results
+ to a File object based on the input information.
+ This utility also allows to locate a file going up in parent
+ levels from the specified file. If the specified file does
+ not exist, or if the coordinates don't make sense, an error
+ is returned.
+
+ Note: the term "file" here might refer to a folder as well
Locates a file based on the relative or absolute
+ location specified. It does not find files, it just results
+ to a File object based on the input information.
+ This utility also allows to locate a file going up in parent
+ levels from the specified file. If the specified file does
+ not exist, or if the coordinates don't make sense, an error
+ is returned
+
+ Note: the term "file" here might refer to a folder as well
Locates a file based on the relative or absolute
+ location specified. It does not find files, it just results
+ to a File object based on the input information.
+ This utility also allows to locate a file going up in parent
+ levels from the specified file. If the specified file does
+ not exist, or if the coordinates don't make sense, an error
+ is returned
+
+ Note: the term "file" here might refer to a folder as well
+
+
Parameters:
+
parentLevel - how many parent levels to be located
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
public MavenGoal setWarnOnError(boolean warnOnError)
+
If this is set to true, then in case the maven goal command
+ does not succeed, then a warn result type will be returned,
+ instead of error. The default value is error.
+
+
Parameters:
+
warnOnError - whether, in case the maven goal command
+ does not succeed, a warn result type should be returned,
+ instead of error
public class RelatedArtifacts
+extends com.paypal.butterfly.extensions.api.TransformationUtility<RelatedArtifacts>
+
Given a list of pom.xml File objects and
+ a parent artifact, this transformation utility results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
This transformation utility, given a list of pom.xml File objects and
+ a parent artifact, results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
This transformation utility, given a list of pom.xml File objects and
+ a parent artifact, results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
+
+
Parameters:
+
parentGroupId - parent group id
+
parentArtifactId - parent artifact id
+
parentVersion - parent version
+
pomFilesAttribute - the name of the transformation context attribute that contains
+ a list of pom.xml files to be analyzed
Given a list of pom.xml File objects and
+ a parent artifact, this transformation utility results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
Given a list of pom.xml File objects and
+ a parent artifact, this transformation utility results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
public class RunScript
+extends com.paypal.butterfly.extensions.api.TransformationUtility<RunScript>
+
Executes a script and saves the result after evaluating it.
+ The scripting language can be chosen, and "js" is the default one.
+ Additionally, one or more objects, and/or transformation context attributes,
+ can be used in the script during transformation time.
Executes a script and saves the result after evaluating it.
+ The scripting language can be chosen, and "js" is the default one.
+ Additionally, one or more objects, and/or transformation context attributes,
+ can be used in the script during transformation time.
Executes a script and saves the result after evaluating it.
+ The scripting language can be chosen, and "js" is the default one.
+ Additionally, one or more objects, and/or transformation context attributes,
+ can be used in the script during transformation time.
public class WebXmlContextParams
+extends com.paypal.butterfly.extensions.api.TransformationUtility<WebXmlContextParams>
+
Parses a Java web deployment descriptor file (web.xml),
+ identifies all context parameters, and save them into a map, the key
+ being param-name and the value being param-value.
+
+ Note: this utility does not validate the file's schema and content,
+ other than what it takes to identify all context-param elements at the document
+ element, and also their respective param-name and param-value elements
Parses a Java web deployment descriptor file (web.xml),
+ identifies all context parameters, and save them into a map, the key
+ being param-name and the value being param-value.
public class ApplyZip
+extends com.paypal.butterfly.extensions.api.TransformationOperation<ApplyZip>
+
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
+
+
Parameters:
+
zipFileUrl - URL string to locate the zip file to be applied
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
+
+
Parameters:
+
zipFileUrl - URL to locate the zip file to be applied
public class CopyDirectory
+extends com.paypal.butterfly.extensions.api.TransformationOperation<A>
+
Copies a directory and its content from one location to another.
+ The files to be copied include sub-folders and their files, coming from relative
+ or absolute location. The path to the files to be copied are preserved, and those
+ folders are also copied to the destination location. If the destination directory
+ does not exist, it is created. But, if it does, then the content to be copied is
+ merged with the destination content, with the source taking precedence.
+
+ Note: if all you want is to copy a set of specific files from one
+ location to another, then use a multiple transformation operation
+ (see TransformationTemplate.addMultiple()) with CopyFile
Operation to copy a directory and its content from one location to another.
+ The files to be copied include sub-folders and their files, coming rom relative
+ or absolute location. The path to the files to be copied are preserved, and those
+ folders are also copied to the destination location. If the destination directory
+ does not exist, it is created. But, if it does, then the content to be copied is
+ merged with the destination content, with the source taking precedence.
Set relative destination location.
+
+ If the relative destination location is NOT known during transformation definition time,
+ then don't set it (leaving as null) and use setToAbsolute(String)
+ based on a transformation context attribute set by a
+ LocateFile
+ transformation utility.
+
+ By setting this relative location, the absolute location attribute name is automatically set to null
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
public A setToAbsolute(String attributeName,
+ String additionalRelativePath)
+
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
+
additionalRelativePath - an additional relative path to be added to the absolute
+ file coming from the transformation context. The path
+ separator will be normalized, similar to what happens
+ in TransformationUtility.relative(String)
getDescription in class com.paypal.butterfly.extensions.api.TransformationUtility<A extends com.paypal.butterfly.utilities.operations.file.AbstractToOperation>
public class CopyFile
+extends com.paypal.butterfly.extensions.api.TransformationOperation<A>
+
Copies a file. The relative or absolute file is the
+ "from" file, while the "to" location is specified via setToRelative(String)
+ or setToAbsolute(String)
+
+ Note: if you want to copy a set of specific files from one
+ location to another, then use a multiple transformation operation
+ (see TransformationTemplate.addMultiple()) with CopyFile. Now, if
+ you want to copy a directory and its content from one location to another, then
+ use CopyDirectory instead.
Set relative destination location.
+
+ If the relative destination location is NOT known during transformation definition time,
+ then don't set it (leaving as null) and use setToAbsolute(String)
+ based on a transformation context attribute set by a
+ LocateFile
+ transformation utility.
+
+ By setting this relative location, the absolute location attribute name is automatically set to null
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
public A setToAbsolute(String attributeName,
+ String additionalRelativePath)
+
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
+
additionalRelativePath - an additional relative path to be added to the absolute
+ file coming from the transformation context. The path
+ separator will be normalized, similar to what happens
+ in TransformationUtility.relative(String)
getDescription in class com.paypal.butterfly.extensions.api.TransformationUtility<A extends com.paypal.butterfly.utilities.operations.file.AbstractToOperation>
public class MoveDirectory
+extends com.paypal.butterfly.extensions.api.TransformationOperation<A>
+
Moves a directory and its content from one location to another.
+ The directory to be moved is specified from relative
+ or absolute location. If the destination directory
+ does not exist, it is created.
Moves a directory and its content from one location to another.
+ The directory to be moved is specified from relative
+ or absolute location. If the destination directory
+ does not exist, it is created.
Set relative destination location.
+
+ If the relative destination location is NOT known during transformation definition time,
+ then don't set it (leaving as null) and use setToAbsolute(String)
+ based on a transformation context attribute set by a
+ LocateFile
+ transformation utility.
+
+ By setting this relative location, the absolute location attribute name is automatically set to null
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
public A setToAbsolute(String attributeName,
+ String additionalRelativePath)
+
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
+
additionalRelativePath - an additional relative path to be added to the absolute
+ file coming from the transformation context. The path
+ separator will be normalized, similar to what happens
+ in TransformationUtility.relative(String)
getDescription in class com.paypal.butterfly.extensions.api.TransformationUtility<A extends com.paypal.butterfly.utilities.operations.file.AbstractToOperation>
public class MoveFile
+extends com.paypal.butterfly.extensions.api.TransformationOperation<A>
+
Moves a file. The relative or absolute file is the
+ "from" file, while the "to" location is specified via setToRelative(String)
+ or setToAbsolute(String)
+
+ Note: if you want to move a set of specific files from one
+ location to another, then use a multiple transformation operation
+ (see TransformationTemplate.addMultiple()) with MoveFile. Now, if
+ you want to move a directory and its content from one location to another, then
+ use MoveDirectory instead.
Set relative destination location.
+
+ If the relative destination location is NOT known during transformation definition time,
+ then don't set it (leaving as null) and use setToAbsolute(String)
+ based on a transformation context attribute set by a
+ LocateFile
+ transformation utility.
+
+ By setting this relative location, the absolute location attribute name is automatically set to null
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
public A setToAbsolute(String attributeName,
+ String additionalRelativePath)
+
The name of the transformation context attribute that holds
+ the absolute destination location.
+
+ If the relative destination location is known during transformation definition time,
+ then don't use this setter, use setToRelative(String) instead.
+
+ By setting this attribute name, the relative destination location is automatically set to null
+
+
Parameters:
+
attributeName - name of the transformation context attribute that holds
+ the absolute destination location
+
additionalRelativePath - an additional relative path to be added to the absolute
+ file coming from the transformation context. The path
+ separator will be normalized, similar to what happens
+ in TransformationUtility.relative(String)
getDescription in class com.paypal.butterfly.extensions.api.TransformationUtility<A extends com.paypal.butterfly.utilities.operations.file.AbstractToOperation>
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
public class PomAddDependency
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomAddDependency>
+implements com.paypal.butterfly.extensions.api.operations.AddElement<PomAddDependency>
public PomAddDependency(String groupId,
+ String artifactId)
+
Operation to add a new dependency to a POM file.
+ This constructor assumes this is a managed dependency, since the version
+ is not set. However, if that is not really the case, during transformation
+ this operation will fail pre-validation.
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomAddParent
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomAddParent>
+implements com.paypal.butterfly.extensions.api.operations.AddElement<PomAddParent>
+
Add a parent artifact in a Maven POM file.
+ By default, if parent is already present, it is overwritten.
+ This behavior though can be changed.
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomAddPlugin
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomAddPlugin>
+implements com.paypal.butterfly.extensions.api.operations.AddElement<PomAddPlugin>
public PomAddPlugin(String groupId,
+ String artifactId)
+
Operation to add a new plugin to a POM file.
+ This constructor assumes this is a managed plugin, since the version
+ is not set. However, if that is not really the case, during transformation
+ this operation will fail pre-validation.
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomChangeDependency
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomChangeDependency>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomChangeDependency>
+
Changes a dependency in a Maven POM file.
+ It allows changing anything but group id and artifact id.
+ It also allows removing specific configuration, letting them
+ to have default values, or be managed when applicable.
+
+ If the dependency to be changed doesn't actually exist, it will result
+ in error
+
+ Important: no check will be done here for possible reasons to break
+ the build, like the lack of version when the dependency is not managed
public PomChangeDependency(String groupId,
+ String artifactId)
+
Operation to change a dependency in a Maven POM file.
+ It allows changing anything but group id and artifact id.
+ It also allows removing specific configuration, letting them
+ to have default values, or be managed when applicable.
+
+ If the dependency to be changed doesn't actually exist, it will result
+ in error
+
+ Important: no check will be done here for possible reasons to break
+ the build, like the lack of version when the dependency is not managed
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomChangeParent
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomChangeParent>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomChangeParent>
+
Changes the parent, or its version, in a Maven POM file.
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomRemoveDependency
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomRemoveDependency>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomRemoveDependency>
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomRemoveManagedDependency
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomRemoveManagedDependency>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomRemoveManagedDependency>
+
Removes a managed dependency entry from a POM file.
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomRemovePlugin
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomRemovePlugin>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomRemovePlugin>
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomRemoveProperty
+extends com.paypal.butterfly.extensions.api.TransformationOperation<T>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomRemoveProperty>
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
public class PomReplaceDependency
+extends com.paypal.butterfly.utilities.operations.pom.AbstractArtifactPomOperation<PomReplaceDependency>
+implements com.paypal.butterfly.extensions.api.operations.ChangeOrRemoveElement<PomReplaceDependency>
+
Replaces a dependency by another one in a POM file.
execution in class com.paypal.butterfly.extensions.api.TransformationUtility<T extends com.paypal.butterfly.utilities.operations.pom.AbstractPomOperation>
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (InsertLine.InsertionMode c : InsertLine.InsertionMode.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
The new line(s) can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
Operation to insert a new line into a text file.
+ The new line will be inserted at the end of the file,
+ unless another insertion method is specified
+
+ See setInsertionMode(InsertionMode).
public InsertLine(String newLine,
+ Integer lineNumber)
+
Operation to insert a new line into a text file.
+ The new line will be inserted at the specified line number
+
+ Notice that the insertion mode is automatically set to
+ InsertLine.InsertionMode.LINE_NUMBER
+
+
Parameters:
+
newLine - the new line to be inserted
+
lineNumber - the line number where the new line will be inserted
Operation to insert a new line into a text file.
+ The new line will be inserted right after only the first
+ line to match the specified regular expression
+
+ Notice that the insertion mode is automatically set to
+ InsertLine.InsertionMode.REGEX_FIRST
+
+
Parameters:
+
newLine - the new line to be inserted
+
regex - the regular expression used to determine where
+ the new line should be inserted
Sets the line number the new line should be added at.
+ Line number for first line is 1.
+ Notice that the insertion mode is automatically set to
+ InsertLine.InsertionMode.LINE_NUMBER.
+
+
Parameters:
+
lineNumber - the line number the new line should be added at
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (InsertText.InsertionMode c : InsertText.InsertionMode.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
public class InsertText
+extends com.paypal.butterfly.extensions.api.TransformationOperation<InsertText>
+
Inserts text from one file into another text file.
+ The text can be inserted:
+
+
InsertionMode.CONCAT: At the final of the file (default)
+
InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+
InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+
InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
+ Notice concat is the default insertion mode. It is also important to state that the text to be inserted will
+ always start on a new line and, if not placed on the end of the file, the continuation of the original text
+ will follow in a new line, even if the inserted text does not end with a line break.
+
+ See setInsertionMode(InsertionMode)
The text can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
Operation to insert text into another text file.
+ The text will be inserted at the end of the file,
+ unless another insertion method is specified
+
+ See setInsertionMode(InsertionMode)
public InsertText(URL textFileUrl,
+ Integer lineNumber)
+
Operation to insert text into another text file.
+ The text will be inserted at the specified line number
+
+ Notice that the insertion mode is automatically set to
+ InsertText.InsertionMode.LINE_NUMBER
+
+
Parameters:
+
textFileUrl - the URL to the text to be inserted
+
lineNumber - the line number the text should be added at
public InsertText(URL textFileUrl,
+ String regex)
+
Operation to insert text into another text file.
+ The text will be inserted right after only the first
+ line to match the specified regular expression
+
+ Notice that the insertion mode is automatically set to
+ InsertText.InsertionMode.REGEX_FIRST
+
+
Parameters:
+
textFileUrl - the URL to the text to be inserted
+
regex - the regular expression to find insertion points
public class RemoveLine
+extends com.paypal.butterfly.utilities.operations.text.AbstractLineOperation<RemoveLine>
+
Removes one, or more, lines from a text file.
+ The line to be removed is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first line found to match it will be removed,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be removed.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
Operation to remove one, or more, lines from a text file.
+ The line to be removed is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first found to match it will be removed,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be removed.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
Operation to remove one, or more, lines from a text file.
+ The line to be removed is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first found to match it will be removed,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be removed.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
+
+
Parameters:
+
regex - the regular expression to identify the line(s) to be removed
public RemoveLine(String regex,
+ boolean firstOnly)
+
Operation to remove one, or more, lines from a text file.
+ The line to be removed is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first found to match it will be removed,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be removed.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
+
+
Parameters:
+
regex - the regular expression to identify the line(s) to be removed
+
firstOnly - if true, only the first line found (from top down) to match
+ the regular expression will be removed. If false, all of them
+ will
public class ReplaceLine
+extends com.paypal.butterfly.utilities.operations.text.AbstractLineOperation<ReplaceLine>
+
Replaces one, or more, lines from a text file.
+ The line to be replace is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first line found to match it will be replaced,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be replaced.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
Operation to replace one, or more, lines from a text file.
+ The line to be replaced is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first found to match it will be replaced,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be replaced.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
public ReplaceLine(String regex,
+ String replacement)
+
Operation to replace one, or more, lines from a text file.
+ The line to be replaced is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first found to match it will be replaced,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be replaced.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
+
+
Parameters:
+
regex - the regular expression to identify the line(s) to be replaced
+
replacement - the replacement line. It is not necessary to add explicitly any
+ end of line (EOL) character in the end of the line, that will be done
+ automatically, but ONLY if the original line has an EOL character too.
+ The same format of EOL character will be preserved.
+ If any EOL character is present anywhere in replacement, it
+ will not be removed nor changed.
public ReplaceLine(String regex,
+ String replacement,
+ boolean firstOnly)
+
Operation to replace one, or more, lines from a text file.
+ The line to be replaced is chosen either based on a regular
+ expression, or by the line number.
+
+ If the regular expression
+ is set, only the first found to match it will be replaced,
+ unless AbstractLineOperation.setFirstOnly(boolean) is set to false, then
+ all lines that match it will be replaced.
+
+ If a regular expression and a line number are both set,
+ the line number will take precedence, and the regular expression
+ will be ignored
+
+
Parameters:
+
regex - the regular expression to identify the line(s) to be replaced
+
replacement - the replacement line. It is not necessary to add explicitly any
+ end of line (EOL) character in the end of the line, that will be done
+ automatically, but ONLY if the original line has an EOL character too.
+ The same format of EOL character will be preserved.
+ If any EOL character is present anywhere in replacement, it
+ will not be removed nor changed.
+
firstOnly - if true, only the first line found (from top down) to match
+ the regular expression will be replaced. If false, all of them
+ will
public ReplaceLine(Integer lineNumber,
+ String replacement)
+
Operation to replace one line from a text file, based on a
+ line number.
+
+
Parameters:
+
replacement - the replacement line. It is not necessary to add explicitly any
+ end of line (EOL) character in the end of the line, that will be done
+ automatically, but ONLY if the original line has an EOL character too.
+ The same format of EOL character will be preserved.
+ If any EOL character is present anywhere in replacement, it
+ will not be removed nor changed.
+
lineNumber - the number of the line to be replaced
replacement - the replacement line. It is not necessary to add explicitly any
+ end of line (EOL) character in the end of the line, that will be done
+ automatically, but ONLY if the original line has an EOL character too.
+ The same format of EOL character will be preserved.
+ If any EOL character is present anywhere in replacement, it
+ will not be removed nor changed.
The new line(s) can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
The text can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
The new line(s) can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
The text can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
public class StringFormat
+extends com.paypal.butterfly.extensions.api.TransformationUtility<StringFormat>
+
Registers a new transformation context
+ attribute by applying one or more existent
+ String transformation context attributes to
+ String.format(String, Object...).
+ The setting order of attributes will be
+ honored when applying the formatting.
Registers a new transformation context
+ attribute by applying one or more existent
+ String transformation context attributes to
+ String.format(String, Object...).
Registers a new transformation context
+ attribute by applying one or more existent
+ String transformation context attributes to
+ String.format(String, Object...).
public class XmlElement
+extends com.paypal.butterfly.extensions.api.TransformationUtility<XmlElement>
+
Retrieves the value of an element,
+ or one of its attributes, in a XML file.
+
+ Note: if more than one element match
+ the specified XML element, the very first
+ one will be used
+
+ If no element, nor attribute, is found,
+ TUExecutionResult.Type.NULL is returned.
+ If the file is not a well formed XML file, an error is returned.
Retrieves the value of an element,
+ or one of its attributes, in a XML file.
+
+ Note: if more than one element match
+ the specified XML element, the very first
+ one will be used
Retrieves the value of an element,
+ or one of its attributes, in a XML file.
+
+ Note: if more than one element match
+ the specified XML element, the very first
+ one will be used
+
+ Specify in xmlElement the XML element whose value, or an attribute, should be
+ the result of this transformation utility. The element specified
+ here should be set based on a path containing all its
+ parent elements separated by '.'. See the example bellow.
+
+ To retrieve the value of the child name, set xmlElement
+ to person.child.name. In this example,
+ that would return Gabriela
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <person>
+ <name>Bruna</name>
+ <child>
+ <name>Gabriela</name>
+ </child>
+ </peson>
+
+
+
Parameters:
+
xmlElement - the XML element whose value, or an attribute, should be
+ the result of this transformation utility
The XML element whose value, or an attribute, should be
+ the result of this transformation utility. The element specified
+ here should be set based on a path containing all its
+ parent elements separated by '.'. See the example bellow.
+
+ To retrieve the value of the child name, set xmlElement
+ to person.child.name. In this example,
+ that would return Gabriela
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <person>
+ <name>Bruna</name>
+ <child>
+ <name>Gabriela</name>
+ </child>
+ </peson>
+
+
+
Parameters:
+
xmlElement - the XML element whose value, or an attribute, should be
+ the result of this transformation utility
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Use
+
Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
+
+
ApplyZip() - Constructor for class com.paypal.butterfly.utilities.operations.file.ApplyZip
+
+
ApplyZip(String) - Constructor for class com.paypal.butterfly.utilities.operations.file.ApplyZip
+
+
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
+
+
ApplyZip(URL) - Constructor for class com.paypal.butterfly.utilities.operations.file.ApplyZip
+
+
Applies the contents of a zip file, whose location is set as a URL,
+ into the transformed application, preserving the relative folders
+ structure inside the zip file.
The new line(s) can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
The text can be inserted:
+
+ InsertionMode.CONCAT: At the final of the file (default)
+ InsertionMode.LINE_NUMBER: At one particular specified line number (first line is number 1)
+ InsertionMode.REGEX_FIRST: Right after only the first line to match the specified regular expression
+ InsertionMode.REGEX_ALL: Right after any line to match the specified regular expression
+
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
+
+
LoadFile() - Constructor for class com.paypal.butterfly.utilities.file.LoadFile
+
+
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
Loads a resource from the classpath, writes it to a temporary file,
+ and then returns a File reference to it, which is saved in the transformation
+ context.
Given a list of pom.xml File objects and
+ a parent artifact, this transformation utility results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
This transformation utility, given a list of pom.xml File objects and
+ a parent artifact, results in a sub-list of those pom.xml files containing only the ones
+ that are, directly or indirectly, a child of the specified parent artifact.
Registers a new transformation context
+ attribute by applying one or more existent
+ String transformation context attributes to
+ String.format(String, Object...).
Parses a Java web deployment descriptor file (web.xml),
+ identifies all context parameters, and save them into a map, the key
+ being param-name and the value being param-value.
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version.