This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new 9066ccc camel-joor: port Java source loader from camel-k to camel 9066ccc is described below commit 9066cccb956436122fa276cbbc019eeb13fdc16e Author: Luca Burgazzoli <lburgazz...@gmail.com> AuthorDate: Fri Feb 5 14:39:19 2021 +0100 camel-joor: port Java source loader from camel-k to camel --- components/camel-joor/pom.xml | 11 ++ .../services/org/apache/camel/routes-loader/java | 2 + .../language/joor/JoorRoutesBuilderLoader.java | 78 +++++++++++++ .../language/joor/JoorRoutesBuilderLoaderTest.java | 130 +++++++++++++++++++++ .../src/test/resources/routes/MyRoutes.java | 25 ++++ .../test/resources/routes/MyRoutesWithBeans.java | 32 +++++ .../test/resources/routes/MyRoutesWithModel.java | 30 +++++ .../resources/routes/MyRoutesWithNestedClass.java | 39 +++++++ .../resources/routes/MyRoutesWithNestedTypes.java | 28 +++++ .../test/resources/routes/MyRoutesWithPackage.java | 11 ++ .../routes/MyRoutesWithPackageAndComment.java | 27 +++++ .../routes/MyRoutesWithPackageAndLineComment.java | 12 ++ .../routes/MyRoutesWithRestConfiguration.java | 30 +++++ .../java/org/apache/camel/util/FileUtilTest.java | 12 ++ .../main/java/org/apache/camel/util/FileUtil.java | 15 ++- 15 files changed, 480 insertions(+), 2 deletions(-) diff --git a/components/camel-joor/pom.xml b/components/camel-joor/pom.xml index ee3607c..89dd949 100644 --- a/components/camel-joor/pom.xml +++ b/components/camel-joor/pom.xml @@ -35,6 +35,12 @@ <properties> <firstVersion>3.7.0</firstVersion> + <sourcecheckExcludes> + **/MyRoutes*.java + </sourcecheckExcludes> + <sourcecheckExcludesComma> + ${sourcecheckExcludes}, + </sourcecheckExcludesComma> </properties> <dependencies> @@ -52,6 +58,11 @@ <!-- test dependencies --> <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test-junit5</artifactId> <scope>test</scope> diff --git a/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/java b/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/java new file mode 100644 index 0000000..d1968d0 --- /dev/null +++ b/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/java @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.language.joor.JoorRoutesBuilderLoader diff --git a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorRoutesBuilderLoader.java b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorRoutesBuilderLoader.java new file mode 100644 index 0000000..131000f --- /dev/null +++ b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorRoutesBuilderLoader.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.language.joor; + +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.spi.Resource; +import org.apache.camel.spi.RoutesBuilderLoader; +import org.apache.camel.spi.annotations.JdkService; +import org.apache.camel.util.FileUtil; +import org.apache.camel.util.IOHelper; +import org.joor.Reflect; + +@JdkService(RoutesBuilderLoader.FACTORY_GROUP + "/" + JoorRoutesBuilderLoader.EXTENSION) +public class JoorRoutesBuilderLoader implements RoutesBuilderLoader, CamelContextAware { + public static final String EXTENSION = "java"; + public static final Pattern PACKAGE_PATTERN = Pattern.compile( + "^\\s*package\\s+([a-zA-Z][\\.\\w]*)\\s*;.*$", Pattern.MULTILINE); + + private CamelContext camelContext; + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public String getSupportedExtension() { + return EXTENSION; + } + + @Override + public RoutesBuilder loadRoutesBuilder(Resource resource) throws Exception { + try (InputStream is = resource.getInputStream()) { + final String content = IOHelper.loadText(is); + final String name = determineName(resource, content); + final Reflect compiled = Reflect.compile(name, content); + + return compiled.create().get(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private String determineName(Resource resource, String content) { + final String name = FileUtil.onlyName(resource.getLocation(), true); + final Matcher matcher = PACKAGE_PATTERN.matcher(content); + + return matcher.find() + ? matcher.group(1) + "." + name + : name; + } +} diff --git a/components/camel-joor/src/test/java/org/apache/camel/language/joor/JoorRoutesBuilderLoaderTest.java b/components/camel-joor/src/test/java/org/apache/camel/language/joor/JoorRoutesBuilderLoaderTest.java new file mode 100644 index 0000000..a19181b --- /dev/null +++ b/components/camel-joor/src/test/java/org/apache/camel/language/joor/JoorRoutesBuilderLoaderTest.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.language.joor; + +import java.util.Collection; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.model.ProcessDefinition; +import org.apache.camel.model.SetBodyDefinition; +import org.apache.camel.model.ToDefinition; +import org.apache.camel.spi.Resource; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JoorRoutesBuilderLoaderTest { + + @ParameterizedTest + @ValueSource(strings = { + "/routes/MyRoutes.java", + "/routes/MyRoutesWithPackage.java", + "/routes/MyRoutesWithPackageAndComment.java", + "/routes/MyRoutesWithPackageAndLineComment.java" + }) + void testLoadRoutes(String location) throws Exception { + try (DefaultCamelContext context = new DefaultCamelContext()) { + Resource resource = Resource.fromClasspath(JoorRoutesBuilderLoaderTest.class, location); + Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource); + + assertThat(builders).hasSize(1); + + RouteBuilder builder = (RouteBuilder) builders.iterator().next(); + builder.setContext(context); + builder.configure(); + + assertThat(builder.getRouteCollection().getRoutes()) + .hasSize(1) + .first() + .satisfies(rd -> { + assertThat(rd.getInput().getEndpointUri()).matches("timer:.*tick"); + assertThat(rd.getOutputs().get(0)).isInstanceOf(ToDefinition.class); + }); + } + } + + @Test + void testLoadRoutesWithNestedClass() throws Exception { + final String location = "/routes/MyRoutesWithNestedClass.java"; + + try (DefaultCamelContext context = new DefaultCamelContext()) { + Resource resource = Resource.fromClasspath(JoorRoutesBuilderLoaderTest.class, location); + Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource); + + assertThat(builders).hasSize(1); + + RouteBuilder builder = (RouteBuilder) builders.iterator().next(); + builder.setContext(context); + builder.configure(); + + assertThat(builder.getRouteCollection().getRoutes()) + .hasSize(1) + .first() + .satisfies(rd -> { + assertThat(rd.getInput().getEndpointUri()).matches("timer:.*tick"); + assertThat(rd.getOutputs().get(0)).isInstanceOf(SetBodyDefinition.class); + assertThat(rd.getOutputs().get(1)).isInstanceOf(ProcessDefinition.class); + assertThat(rd.getOutputs().get(2)).isInstanceOf(ToDefinition.class); + }); + } + } + + @Test + void testLoadRoutesWithRestConfiguration() throws Exception { + final String location = "/routes/MyRoutesWithRestConfiguration.java"; + + try (DefaultCamelContext context = new DefaultCamelContext()) { + Resource resource = Resource.fromClasspath(JoorRoutesBuilderLoaderTest.class, location); + Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource); + + assertThat(builders).hasSize(1); + + RouteBuilder builder = (RouteBuilder) builders.iterator().next(); + builder.setContext(context); + builder.configure(); + + assertThat(builder.getRestConfiguration()) + .hasFieldOrPropertyWithValue("component", "restlet"); + } + } + + @Test + void testLoadRoutesWithModel() throws Exception { + final String location = "/routes/MyRoutesWithModel.java"; + + try (DefaultCamelContext context = new DefaultCamelContext()) { + Resource resource = Resource.fromClasspath(JoorRoutesBuilderLoaderTest.class, location); + Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource); + + assertThat(builders).hasSize(1); + + RouteBuilder builder = (RouteBuilder) builders.iterator().next(); + builder.setContext(context); + builder.configure(); + + assertThat(builder.getRestCollection().getRests()).anySatisfy(rd -> { + assertThat(rd.getVerbs()) + .first() + .hasFieldOrPropertyWithValue("outType", MyUser.class.getName()); + }); + } + } +} diff --git a/components/camel-joor/src/test/resources/routes/MyRoutes.java b/components/camel-joor/src/test/resources/routes/MyRoutes.java new file mode 100644 index 0000000..0d0b57c --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutes.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutes extends RouteBuilder { + @Override + public void configure() throws Exception { + from("timer:tick") + .to("log:info"); + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithBeans.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithBeans.java new file mode 100644 index 0000000..746b8e6 --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithBeans.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.BindToRegistry; +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithBeans extends RouteBuilder { + @Override + public void configure() throws Exception { + from("direct:start") + .setBody().simple("${header[MyHeader]}") + .to("log:knative"); + } + + @BindToRegistry("my-bean") + public static String myBean() { + return "my-bean-string"; + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithModel.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithModel.java new file mode 100644 index 0000000..e434b2d --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithModel.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithModel extends RouteBuilder { + @Override + public void configure() throws Exception { + rest("/say") + .get("/emp/{id}") + .outType(org.apache.camel.language.joor.MyUser.class) + .to("direct:getEmployee"); + + from("direct:getEmployee") + .to("log:getEmployee"); + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithNestedClass.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithNestedClass.java new file mode 100644 index 0000000..e4c2944 --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithNestedClass.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithNestedClass extends RouteBuilder { + @Override + public void configure() throws Exception { + Processor toUpper = new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + String body = exchange.getIn().getBody(String.class); + body = body.toUpperCase(); + + exchange.getOut().setBody(body); + } + }; + + from("timer:tick") + .setBody().constant("test") + .process(toUpper) + .to("log:info"); + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithNestedTypes.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithNestedTypes.java new file mode 100644 index 0000000..1e0d168 --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithNestedTypes.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithNestedTypes extends RouteBuilder { + @Override + public void configure() throws Exception { + } + + public static class MyModel { + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithPackage.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithPackage.java new file mode 100644 index 0000000..ab377ce --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithPackage.java @@ -0,0 +1,11 @@ +package my.routes; + +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithPackage extends RouteBuilder { + @Override + public void configure() throws Exception { + from("timer:tick") + .to("log:info"); + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithPackageAndComment.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithPackageAndComment.java new file mode 100644 index 0000000..7487985 --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithPackageAndComment.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package my.routes; + +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithPackageAndComment extends RouteBuilder { + @Override + public void configure() throws Exception { + from("timer:tick") + .to("log:info"); + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithPackageAndLineComment.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithPackageAndLineComment.java new file mode 100644 index 0000000..800131d --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithPackageAndLineComment.java @@ -0,0 +1,12 @@ +// camel-k: language=java +package my.routes; + +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithPackageAndLineComment extends RouteBuilder { + @Override + public void configure() throws Exception { + from("timer:tick") + .to("log:info"); + } +} \ No newline at end of file diff --git a/components/camel-joor/src/test/resources/routes/MyRoutesWithRestConfiguration.java b/components/camel-joor/src/test/resources/routes/MyRoutesWithRestConfiguration.java new file mode 100644 index 0000000..ffb9229 --- /dev/null +++ b/components/camel-joor/src/test/resources/routes/MyRoutesWithRestConfiguration.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesWithRestConfiguration extends RouteBuilder { + @Override + public void configure() throws Exception { + restConfiguration() + .component("restlet") + .host("localhost") + .port("8080"); + + from("timer:tick") + .to("log:info"); + } +} \ No newline at end of file diff --git a/core/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java b/core/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java index 1fea8e0..39a9df6 100644 --- a/core/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java @@ -154,6 +154,18 @@ public class FileUtilTest { } @Test + public void testOnlyName() { + assertEquals(null, FileUtil.onlyName(null)); + assertEquals("foo", FileUtil.onlyName("foo")); + assertEquals("foo", FileUtil.onlyName("foo.xml")); + assertEquals("bar", FileUtil.onlyName("foo/bar.xml")); + assertEquals("bar", FileUtil.onlyName("/foo/bar.xml")); + assertEquals("baz", FileUtil.onlyName("/foo/bar/baz.xml")); + assertEquals("foo", FileUtil.onlyName("/foo.xml")); + assertEquals("foo", FileUtil.onlyName("/bar/foo.xml")); + } + + @Test public void testCompactPath() { assertEquals(null, FileUtil.compactPath(null)); if (FileUtil.isWindows()) { diff --git a/core/camel-util/src/main/java/org/apache/camel/util/FileUtil.java b/core/camel-util/src/main/java/org/apache/camel/util/FileUtil.java index 1cf328b..e4c23cb 100644 --- a/core/camel-util/src/main/java/org/apache/camel/util/FileUtil.java +++ b/core/camel-util/src/main/java/org/apache/camel/util/FileUtil.java @@ -150,7 +150,7 @@ public final class FileUtil { String s = name; - // there must be some leading text, as we should only remove trailing separators + // there must be some leading text, as we should only remove trailing separators while (s.endsWith("/") || s.endsWith(File.separator)) { s = s.substring(0, s.length() - 1); } @@ -254,6 +254,17 @@ public final class FileUtil { return null; } + public static String onlyName(String name) { + return onlyName(name, false); + } + + public static String onlyName(String name, boolean singleMode) { + name = FileUtil.stripPath(name); + name = FileUtil.stripExt(name, singleMode); + + return name; + } + /** * Compacts a path by stacking it and reducing <tt>..</tt>, and uses OS specific file separators (eg * {@link java.io.File#separator}). @@ -425,7 +436,7 @@ public final class FileUtil { /** * Rename file using copy and delete strategy. This is primarily used in environments where the regular rename * operation is unreliable. - * + * * @param from the file to be renamed * @param to the new target file * @return <tt>true</tt> if the file was renamed successfully, otherwise <tt>false</tt>