Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.fabric8.forge.camel.commands.project.ConfigureEndpointPropertiesStep Maven / Gradle / Ivy
/**
* Copyright 2005-2015 Red Hat, Inc.
*
* Red Hat 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 io.fabric8.forge.camel.commands.project;
import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import io.fabric8.forge.addon.utils.LineNumberHelper;
import io.fabric8.forge.addon.utils.XmlLineNumberParser;
import io.fabric8.forge.camel.commands.project.helper.CamelJavaParserHelper;
import io.fabric8.forge.camel.commands.project.helper.PoorMansLogger;
import io.fabric8.forge.camel.commands.project.helper.StringHelper;
import io.fabric8.forge.camel.commands.project.model.CamelComponentDetails;
import org.apache.camel.catalog.CamelCatalog;
import org.jboss.forge.addon.parser.java.facets.JavaSourceFacet;
import org.jboss.forge.addon.parser.java.resources.JavaResource;
import org.jboss.forge.addon.projects.Project;
import org.jboss.forge.addon.projects.ProjectFactory;
import org.jboss.forge.addon.projects.dependencies.DependencyInstaller;
import org.jboss.forge.addon.projects.facets.ResourcesFacet;
import org.jboss.forge.addon.projects.facets.WebResourcesFacet;
import org.jboss.forge.addon.resource.FileResource;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIContext;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.context.UINavigationContext;
import org.jboss.forge.addon.ui.input.InputComponent;
import org.jboss.forge.addon.ui.metadata.UICommandMetadata;
import org.jboss.forge.addon.ui.result.NavigationResult;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;
import org.jboss.forge.addon.ui.util.Categories;
import org.jboss.forge.addon.ui.util.Metadata;
import org.jboss.forge.addon.ui.wizard.UIWizardStep;
import org.jboss.forge.roaster.model.source.AnnotationSource;
import org.jboss.forge.roaster.model.source.FieldSource;
import org.jboss.forge.roaster.model.source.JavaClassSource;
import org.jboss.forge.roaster.model.source.MethodSource;
import org.jboss.forge.roaster.model.util.Strings;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import static io.fabric8.forge.addon.utils.CamelProjectHelper.findCamelArtifactDependency;
import static io.fabric8.forge.camel.commands.project.helper.CamelXmlHelper.isCamelContextOrRoutesNode;
import static io.fabric8.forge.camel.commands.project.helper.CamelCatalogHelper.getPrefix;
import static io.fabric8.forge.camel.commands.project.helper.CamelCatalogHelper.isDefaultValue;
import static io.fabric8.forge.camel.commands.project.helper.CamelCatalogHelper.isMultiValue;
import static io.fabric8.forge.camel.commands.project.helper.CamelCatalogHelper.isNonePlaceholderEnumValue;
import static io.fabric8.forge.camel.commands.project.helper.CamelCommandsHelper.ensureCamelArtifactIdAdded;
import static io.fabric8.forge.camel.commands.project.helper.CamelCommandsHelper.loadCamelComponentDetails;
import static io.fabric8.forge.camel.commands.project.helper.CamelXmlHelper.getCamelContextElements;
public class ConfigureEndpointPropertiesStep extends AbstractCamelProjectCommand implements UIWizardStep {
private static final PoorMansLogger LOG = new PoorMansLogger(false);
private final DependencyInstaller dependencyInstaller;
private final CamelCatalog camelCatalog;
private final String componentName;
private final String group;
private final List allInputs;
private final List inputs;
private final boolean last;
private final int index;
private final int total;
public ConfigureEndpointPropertiesStep(ProjectFactory projectFactory,
DependencyInstaller dependencyInstaller,
CamelCatalog camelCatalog,
String componentName, String group,
List allInputs,
List inputs,
boolean last, int index, int total) {
this.projectFactory = projectFactory;
this.dependencyInstaller = dependencyInstaller;
this.camelCatalog = camelCatalog;
this.componentName = componentName;
this.group = group;
this.allInputs = allInputs;
this.inputs = inputs;
this.last = last;
// we want to 1-based
this.index = index + 1;
this.total = total;
}
public String getGroup() {
return group;
}
public int getIndex() {
return index;
}
public int getTotal() {
return total;
}
@Override
public UICommandMetadata getMetadata(UIContext context) {
return Metadata.forCommand(ConfigureEndpointPropertiesStep.class).name(
"Camel: Endpoint options").category(Categories.create(CATEGORY))
.description(String.format("Configure %s options (%s of %s)", group, index, total));
}
@Override
@SuppressWarnings("unchecked")
public void initializeUI(UIBuilder builder) throws Exception {
if (inputs != null) {
for (InputComponent input : inputs) {
builder.add(input);
}
}
}
@Override
public NavigationResult next(UINavigationContext context) throws Exception {
return null;
}
@Override
public Result execute(UIExecutionContext context) throws Exception {
Map attributeMap = context.getUIContext().getAttributeMap();
// only execute if we are last
if (last) {
String kind = mandatoryAttributeValue(attributeMap, "kind");
if ("xml".equals(kind)) {
return executeXml(context, attributeMap);
} else if ("java".equals(kind)) {
return executeJava(context, attributeMap);
} else {
return executeOther(context, attributeMap);
}
} else {
return null;
}
}
protected Result executeXml(UIExecutionContext context, Map attributeMap) throws Exception {
String camelComponentName = optionalAttributeValue(attributeMap, "componentName");
String endpointInstanceName = optionalAttributeValue(attributeMap, "instanceName");
String mode = mandatoryAttributeValue(attributeMap, "mode");
String xml = mandatoryAttributeValue(attributeMap, "xml");
// edit mode includes the existing uri and line number
String lineNumber = null;
String lineNumberEnd = null;
String endpointUrl = null;
if ("edit".equals(mode)) {
lineNumber = mandatoryAttributeValue(attributeMap, "lineNumber");
lineNumberEnd = optionalAttributeValue(attributeMap, "lineNumberEnd");
endpointUrl = mandatoryAttributeValue(attributeMap, "endpointUri");
// since this is XML we need to escape & as &
// to be safe that & is not already & we need to revert it first
endpointUrl = StringHelper.replaceAll(endpointUrl, "&", "&");
endpointUrl = StringHelper.replaceAll(endpointUrl, "&", "&");
endpointUrl = StringHelper.replaceAll(endpointUrl, "<", "<");
endpointUrl = StringHelper.replaceAll(endpointUrl, ">", ">");
}
Project project = getSelectedProject(context);
ResourcesFacet facet = project.getFacet(ResourcesFacet.class);
WebResourcesFacet webResourcesFacet = null;
if (project.hasFacet(WebResourcesFacet.class)) {
webResourcesFacet = project.getFacet(WebResourcesFacet.class);
}
// lets find the camel component class
CamelComponentDetails details = new CamelComponentDetails();
Result result = loadCamelComponentDetails(camelCatalog, camelComponentName, details);
if (result != null) {
return result;
}
// and make sure its dependency is added
result = ensureCamelArtifactIdAdded(project, details, dependencyInstaller);
if (result != null) {
return result;
}
// collect all the options that was set
Map options = new HashMap();
for (InputComponent input : allInputs) {
String key = input.getName();
// only use the value if a value was set (and the value is not the same as the default value)
if (input.hasValue()) {
String value = input.getValue().toString();
if (value != null) {
// special for multivalued options
boolean isMultiValue = isMultiValue(camelCatalog, camelComponentName, key);
if (isMultiValue) {
String prefix = getPrefix(camelCatalog, camelComponentName, key);
// ensure the value has prefix for all its options
// and make sure to adjust & to & if in xml
// since this is XML we need to escape & as &
// to be safe that & is not already & we need to revert it first
value = StringHelper.replaceAll(value, "&", "&");
value = StringHelper.replaceAll(value, "&", "&");
// rebuild value (accordingly to above comment)
StringBuilder sb = new StringBuilder();
String[] parts = value.split("&");
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
if (!part.startsWith(prefix)) {
part = prefix + part;
}
sb.append(part);
if (i < parts.length - 1) {
// since this is xml then use & as separator
sb.append("&");
}
}
value = sb.toString();
}
boolean matchDefault = isDefaultValue(camelCatalog, camelComponentName, key, value);
if ("none".equals(value)) {
// special for enum that may have a none as dummy placeholder which we should not add
boolean nonePlaceholder = isNonePlaceholderEnumValue(camelCatalog, camelComponentName, key);
if (!matchDefault && !nonePlaceholder) {
options.put(key, value);
}
} else if (!matchDefault) {
options.put(key, value);
}
}
} else if (input.isRequired() && input.hasDefaultValue()) {
// if its required then we need to grab the value
String value = input.getValue().toString();
if (value != null) {
options.put(key, value);
}
}
}
LOG.info("Creating uri with component: " + componentName + " and options:" + options);
String uri = camelCatalog.asEndpointUriXml(camelComponentName, options, false);
LOG.info("Uri created: " + uri);
if (uri == null) {
return Results.fail("Cannot create endpoint uri");
}
LOG.info("Loading XML file " + xml);
FileResource file = facet != null ? facet.getResource(xml) : null;
if (file == null || !file.exists()) {
file = webResourcesFacet != null ? webResourcesFacet.getWebResource(xml) : null;
}
if (file == null || !file.exists()) {
return Results.fail("Cannot find XML file " + xml);
}
String cursorPosition = optionalAttributeValue(attributeMap, "cursorPosition");
if (cursorPosition != null) {
return addEndpointXml(file, uri, endpointInstanceName, xml, cursorPosition);
} else {
return addOrEditEndpointXml(file, uri, endpointUrl, endpointInstanceName, xml, lineNumber, lineNumberEnd);
}
}
protected Result addOrEditEndpointXml(FileResource file, String uri, String endpointUrl, String endpointInstanceName, String xml, String lineNumber, String lineNumberEnd) throws Exception {
// if we have a line number then use that to edit the existing value
if (lineNumber != null) {
List lines = LineNumberHelper.readLines(file.getResourceInputStream());
return editEndpointXml(lines, lineNumber, endpointUrl, uri, file, xml);
} else {
// we are in add mode, so parse dom to find and insert the endpoint where its needed
Document root = XmlLineNumberParser.parseXml(file.getResourceInputStream());
return addEndpointXml(root, endpointInstanceName, uri, file, xml);
}
}
private Result editEndpointXml(List lines, String lineNumber, String endpointUrl, String uri, FileResource file, String xml) {
// the list is 0-based, and line number is 1-based
int idx = Integer.valueOf(lineNumber) - 1;
String line = lines.get(idx);
// replace uri with new value
line = StringHelper.replaceAll(line, endpointUrl, uri);
lines.set(idx, line);
LOG.info("Updating " + endpointUrl + " to " + uri + " at line " + lineNumber + " in file " + xml);
// and save the file back
String content = LineNumberHelper.linesToString(lines);
file.setContents(content);
return Results.success("Update endpoint uri: " + uri + " in file " + xml);
}
private Result addEndpointXml(Document root, String endpointInstanceName, String uri, FileResource file, String xml) throws Exception {
String lineNumber;
// The DOM api is so fucking terrible!
if (root != null) {
NodeList camels = getCamelContextElements(root);
// TODO: what about 2+ camel's ?
if (camels != null && camels.getLength() == 1) {
Node camel = camels.item(0);
Node camelContext = null;
boolean created = false;
// find existing by id
Node found = null;
for (int i = 0; i < camel.getChildNodes().getLength(); i++) {
if (isCamelContextOrRoutesNode(camel)) {
camelContext = camel;
}
Node child = camel.getChildNodes().item(i);
if (isCamelContextOrRoutesNode(child)) {
camelContext = child;
}
if ("endpoint".equals(child.getNodeName())) {
// okay its an endpoint so if we can match by id attribute
String id = child.getAttributes().getNamedItem("id").getNodeValue();
if (endpointInstanceName.equals(id)) {
found = child;
break;
}
}
}
int extraSpaces = 0;
int extraLines = 0;
if (found == null) {
created = true;
found = insertEndpointBefore(camel);
if (found == null) {
// empty so use node
found = camelContext;
extraSpaces = 2;
extraLines = 1;
}
}
if (found == null) {
return Results.fail("Cannot find or in XML file " + xml);
}
lineNumber = (String) found.getUserData(XmlLineNumberParser.LINE_NUMBER);
// if we created a new endpoint, then insert a new line with the endpoint details
List lines = LineNumberHelper.readLines(file.getResourceInputStream());
String line = String.format("", endpointInstanceName, uri);
// the list is 0-based, and line number is 1-based
int idx = lineNumber != null ? Integer.valueOf(lineNumber) - 1 : 0;
idx += extraLines;
int spaces = LineNumberHelper.leadingSpaces(lines, idx) + extraSpaces;
line = LineNumberHelper.padString(line, spaces);
if (created) {
lines.add(idx, line);
} else {
lines.set(idx, line);
}
// and save the file back
String content = LineNumberHelper.linesToString(lines);
file.setContents(content);
}
}
return Results.success("Added endpoint uri: " + uri + " in XML file " + xml);
}
private Result addEndpointXml(FileResource file, String uri, String endpointInstanceName, String xml, String cursorPosition) throws Exception {
LOG.info("Adding uri " + uri + " at position " + cursorPosition + " in file " + xml);
// we do not want to change the current code formatting so we need to search
// replace the unformatted class source code
StringBuilder sb = new StringBuilder(file.getContents());
int pos = Integer.valueOf(cursorPosition);
// move to end if pos is after the content
pos = Math.min(sb.length(), pos);
LOG.info("Adding endpoint at pos: " + pos + " in file: " + xml);
// check if prev and next is a quote and if not then add it automatic
int prev = pos - 1;
int next = pos + 1;
char ch = sb.charAt(prev);
char ch2 = next < sb.length() ? sb.charAt(next) : ' ';
if (ch != '"' && ch2 != '"') {
uri = "\"" + uri + "\"";
}
// insert uri at position
sb.insert(pos, uri);
String text = sb.toString();
// use this code currently to save content unformatted
file.setContents(text);
return Results.success("Added endpoint " + uri + " in " + xml);
}
protected Result executeJava(UIExecutionContext context, Map attributeMap) throws Exception {
String camelComponentName = mandatoryAttributeValue(attributeMap, "componentName");
String endpointInstanceName = optionalAttributeValue(attributeMap, "instanceName");
String mode = mandatoryAttributeValue(attributeMap, "mode");
String routeBuilder = mandatoryAttributeValue(attributeMap, "routeBuilder");
// edit mode includes the existing uri and line number
String lineNumber = null;
String lineNumberEnd = null;
String endpointUrl = null;
if ("edit".equals(mode)) {
lineNumber = mandatoryAttributeValue(attributeMap, "lineNumber");
lineNumberEnd = optionalAttributeValue(attributeMap, "lineNumberEnd");
endpointUrl = mandatoryAttributeValue(attributeMap, "endpointUri");
}
Project project = getSelectedProject(context);
JavaSourceFacet facet = project.getFacet(JavaSourceFacet.class);
// lets find the camel component class
CamelComponentDetails details = new CamelComponentDetails();
Result result = loadCamelComponentDetails(camelCatalog, camelComponentName, details);
if (result != null) {
return result;
}
// and make sure its dependency is added
result = ensureCamelArtifactIdAdded(project, details, dependencyInstaller);
if (result != null) {
return result;
}
// collect all the options that was set
Map options = new HashMap();
for (InputComponent input : allInputs) {
String key = input.getName();
// only use the value if a value was set (and the value is not the same as the default value)
if (input.hasValue()) {
String value = input.getValue().toString();
if (value != null) {
// special for multivalued options
boolean isMultiValue = isMultiValue(camelCatalog, camelComponentName, key);
if (isMultiValue) {
String prefix = getPrefix(camelCatalog, camelComponentName, key);
// ensure the value has prefix for all its options
// and make sure to adjust & (we replace to xml style)
value = StringHelper.replaceAll(value, "&", "&");
value = StringHelper.replaceAll(value, "&", "&");
// rebuild value (accordingly to above comment)
StringBuilder sb = new StringBuilder();
String[] parts = value.split("&");
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
if (!part.startsWith(prefix)) {
part = prefix + part;
}
sb.append(part);
if (i < parts.length - 1) {
// since this is java then use & as separator
sb.append("&");
}
}
value = sb.toString();
}
boolean matchDefault = isDefaultValue(camelCatalog, camelComponentName, key, value);
if ("none".equals(value)) {
// special for enum that may have a none as dummy placeholder which we should not add
boolean nonePlaceholder = isNonePlaceholderEnumValue(camelCatalog, camelComponentName, key);
if (!matchDefault && !nonePlaceholder) {
options.put(key, value);
}
} else if (!matchDefault) {
options.put(key, value);
}
}
} else if (input.isRequired() && input.hasDefaultValue()) {
// if its required then we need to grab the value
String value = input.getValue().toString();
if (value != null) {
options.put(key, value);
}
}
}
LOG.info("Creating uri with component: " + componentName + " and options:" + options);
String uri = camelCatalog.asEndpointUri(camelComponentName, options, false);
LOG.info("Uri created: " + uri);
if (uri == null) {
return Results.fail("Cannot create endpoint uri");
}
LOG.info("Loading Java file " + routeBuilder);
JavaResource file = facet.getJavaResource(routeBuilder);
if (file == null || !file.exists()) {
return Results.fail("RouteBuilder " + routeBuilder + " does not exist");
}
String cursorPosition = optionalAttributeValue(attributeMap, "cursorPosition");
if (cursorPosition != null) {
return addEndpointJava(project, facet, file, uri, endpointInstanceName, routeBuilder, cursorPosition);
} else {
return addOrEditEndpointJava(project, facet, file, uri, endpointUrl, endpointInstanceName, routeBuilder, lineNumber, lineNumberEnd);
}
}
protected Result addOrEditEndpointJava(Project project, JavaSourceFacet facet, JavaResource file, String uri, String endpointUrl,
String endpointInstanceName, String routeBuilder, String lineNumber, String lineNumberEnd) throws Exception {
JavaClassSource clazz = file.getJavaType();
boolean updated = true;
boolean newCode = false;
if (endpointInstanceName != null) {
// add the endpoint as a field
// special for CDI as we use different set of annotations
FieldSource field = clazz.getField(endpointInstanceName);
AnnotationSource annotation;
if (field == null) {
field = clazz.addField();
field.setName(endpointInstanceName);
field.setType("org.apache.camel.Endpoint");
field.setPrivate();
updated = false;
newCode = true;
}
boolean cdi = findCamelArtifactDependency(project, "camel-cdi") != null;
if (cdi) {
// cdi uses @Inject @Uri
if (!field.hasAnnotation("javax.inject.Inject")) {
field.addAnnotation("javax.inject.Inject");
newCode = true;
}
if (!field.hasAnnotation("org.apache.camel.cdi.Uri")) {
field.addAnnotation("org.apache.camel.cdi.Uri");
newCode = true;
}
annotation = field.getAnnotation("org.apache.camel.cdi.Uri");
annotation.setStringValue(uri);
} else {
if (!field.hasAnnotation("org.apache.camel.EndpointInject")) {
field.addAnnotation("org.apache.camel.EndpointInject");
newCode = true;
}
annotation = field.getAnnotation("org.apache.camel.EndpointInject");
annotation.setStringValue("uri", uri);
}
if (!clazz.hasImport("org.apache.camel.Endpoint")) {
// make sure to import what we use
clazz.addImport("org.apache.camel.Endpoint");
newCode = true;
}
if (cdi) {
if (!clazz.hasImport("javax.inject.Inject")) {
clazz.addImport("javax.inject.Inject");
newCode = true;
}
if (!clazz.hasImport("org.apache.camel.cdi.Uri")) {
clazz.addImport("org.apache.camel.cdi.Uri");
newCode = true;
}
} else {
if (!clazz.hasImport("org.apache.camel.EndpointInject")) {
clazz.addImport("org.apache.camel.EndpointInject");
newCode = true;
}
}
// attempt to read the line number and do a search/replace and save, to avoid re-formatting the source code.
if (!newCode && lineNumber != null) {
List lines = LineNumberHelper.readLines(file.getResourceInputStream());
// the list is 0-based, and line number is 1-based
int idx = Integer.valueOf(lineNumber) - 1;
if (idx <= lines.size()) {
String line = lines.get(idx);
// wonder if we should have better way, than a replaceFirst?
String find = Pattern.quote(endpointUrl);
line = line.replaceFirst(find, uri);
// update the line
lines.set(idx, line);
// and save the file back
String content = LineNumberHelper.linesToString(lines);
file.setContents(content);
} else {
// okay give up and just use roaster to save it as it if was new-code
newCode = true;
}
}
if (newCode) {
facet.saveJavaSource(clazz);
}
if (updated) {
return Results.success("Updated endpoint " + endpointInstanceName + " in " + routeBuilder);
} else {
return Results.success("Added endpoint " + endpointInstanceName + " in " + routeBuilder);
}
} else {
MethodSource method = CamelJavaParserHelper.findConfigureMethod(clazz);
if (method != null) {
// we do not want to change the current code formatting so we need to search
// replace the unformatted class soucre code
String code = clazz.toUnformattedString();
// TODO: we can use the line number to find where we start at least
// wonder if we should have better way, than a replaceFirst?
String find = Pattern.quote(endpointUrl);
code = code.replaceFirst(find, uri);
// use this code currently to save content unformatted
file.setContents(new ByteArrayInputStream(code.getBytes()), null);
return Results.success("Updated endpoint " + endpointUrl + " -> " + uri + " in " + routeBuilder);
}
}
return Results.fail("Cannot update endpoint");
}
protected Result addEndpointJava(Project project, JavaSourceFacet facet, JavaResource file, String uri,
String endpointInstanceName, String routeBuilder, String cursorPosition) throws Exception {
JavaClassSource clazz = file.getJavaType();
// we do not want to change the current code formatting so we need to search
// replace the unformatted class source code
StringBuilder sb = new StringBuilder(clazz.toUnformattedString());
int pos = Integer.valueOf(cursorPosition);
// move to end if pos is after the content
pos = Math.min(sb.length(), pos);
LOG.info("Adding endpoint at pos: " + pos + " in file: " + routeBuilder);
// check if prev and next is a quote and if not then add it automatic
int prev = pos - 1;
int next = pos + 1;
char ch = sb.charAt(prev);
char ch2 = next < sb.length() ? sb.charAt(next) : ' ';
if (ch != '"' && ch2 != '"') {
uri = "\"" + uri + "\"";
}
// insert uri at position
sb.insert(pos, uri);
// use this code currently to save content unformatted
file.setContents(sb.toString());
return Results.success("Added endpoint " + uri + " in " + routeBuilder);
}
protected Result executeOther(UIExecutionContext context, Map attributeMap) throws Exception {
String camelComponentName = mandatoryAttributeValue(attributeMap, "componentName");
String mode = mandatoryAttributeValue(attributeMap, "mode");
String currentFile = mandatoryAttributeValue(attributeMap, "currentFile");
// TODO: add support for edit
// edit mode includes the existing uri and line number
String lineNumber = null;
String lineNumberEnd = null;
String endpointUrl = null;
if ("edit".equals(mode)) {
lineNumber = mandatoryAttributeValue(attributeMap, "lineNumber");
lineNumberEnd = optionalAttributeValue(attributeMap, "lineNumberEnd");
endpointUrl = mandatoryAttributeValue(attributeMap, "endpointUri");
}
Project project = getSelectedProject(context);
ResourcesFacet facet = project.getFacet(ResourcesFacet.class);
WebResourcesFacet webResourcesFacet = null;
if (project.hasFacet(WebResourcesFacet.class)) {
webResourcesFacet = project.getFacet(WebResourcesFacet.class);
}
// lets find the camel component class
CamelComponentDetails details = new CamelComponentDetails();
Result result = loadCamelComponentDetails(camelCatalog, camelComponentName, details);
if (result != null) {
return result;
}
// and make sure its dependency is added
result = ensureCamelArtifactIdAdded(project, details, dependencyInstaller);
if (result != null) {
return result;
}
// collect all the options that was set
Map options = new HashMap();
for (InputComponent input : allInputs) {
String key = input.getName();
// only use the value if a value was set (and the value is not the same as the default value)
if (input.hasValue()) {
String value = input.getValue().toString();
if (value != null) {
// special for multivalued options
boolean isMultiValue = isMultiValue(camelCatalog, camelComponentName, key);
if (isMultiValue) {
String prefix = getPrefix(camelCatalog, camelComponentName, key);
// ensure the value has prefix for all its options
// and make sure to adjust & (we replace to xml style)
value = StringHelper.replaceAll(value, "&", "&");
value = StringHelper.replaceAll(value, "&", "&");
// rebuild value (accordingly to above comment)
StringBuilder sb = new StringBuilder();
String[] parts = value.split("&");
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
if (!part.startsWith(prefix)) {
part = prefix + part;
}
sb.append(part);
if (i < parts.length - 1) {
// since this is java then use & as separator
sb.append("&");
}
}
value = sb.toString();
}
boolean matchDefault = isDefaultValue(camelCatalog, camelComponentName, key, value);
if ("none".equals(value)) {
// special for enum that may have a none as dummy placeholder which we should not add
boolean nonePlaceholder = isNonePlaceholderEnumValue(camelCatalog, camelComponentName, key);
if (!matchDefault && !nonePlaceholder) {
options.put(key, value);
}
} else if (!matchDefault) {
options.put(key, value);
}
}
} else if (input.isRequired() && input.hasDefaultValue()) {
// if its required then we need to grab the value
String value = input.getValue().toString();
if (value != null) {
options.put(key, value);
}
}
}
LOG.info("Creating uri with component: " + componentName + " and options:" + options);
String uri = camelCatalog.asEndpointUri(camelComponentName, options, false);
LOG.info("Uri created: " + uri);
if (uri == null) {
return Results.fail("Cannot create endpoint uri");
}
LOG.info("Loading resource file " + currentFile);
FileResource file = facet != null ? facet.getResource(currentFile) : null;
if (file == null || !file.exists()) {
file = webResourcesFacet != null ? webResourcesFacet.getWebResource(currentFile) : null;
}
if (file == null || !file.exists()) {
return Results.fail("Cannot find resource file " + currentFile);
}
String cursorPosition = optionalAttributeValue(attributeMap, "cursorPosition");
if ("edit".equals(mode)) {
return editEndpointOther(project, facet, file, uri, endpointUrl, currentFile, lineNumber);
} else {
return addEndpointOther(project, facet, file, uri, currentFile, cursorPosition);
}
}
protected Result editEndpointOther(Project project, ResourcesFacet facet, FileResource file, String uri, String endpointUrl,
String currentFile, String lineNumber) throws Exception {
List lines = LineNumberHelper.readLines(file.getResourceInputStream());
// the list is 0-based, and line number is 1-based
int idx = Integer.valueOf(lineNumber) - 1;
String line = lines.get(idx);
// replace uri with new value
line = StringHelper.replaceAll(line, endpointUrl, uri);
lines.set(idx, line);
LOG.info("Updating " + endpointUrl + " to " + uri + " at line " + lineNumber + " in file " + currentFile);
// and save the file back
String content = LineNumberHelper.linesToString(lines);
file.setContents(content);
return Results.success("Update endpoint uri: " + uri + " in file " + currentFile);
}
protected Result addEndpointOther(Project project, ResourcesFacet facet, FileResource file, String uri,
String currentFile, String cursorPosition) throws Exception {
StringBuilder sb = new StringBuilder(file.getContents());
int pos = Integer.valueOf(cursorPosition);
// move to end if pos is after the content
pos = Math.min(sb.length(), pos);
LOG.info("Adding endpoint at pos: " + pos + " in file: " + currentFile);
// insert uri at position
sb.insert(pos, uri);
// use this code currently to save content unformatted
file.setContents(sb.toString());
return Results.success("Added endpoint " + uri + " in " + currentFile);
}
/**
* To find the closet node that we need to insert the endpoints before, so the Camel schema is valid.
*/
private Node insertEndpointBefore(Node camel) {
// if there is endpoints then the cut-off is after the last
Node endpoint = null;
for (int i = 0; i < camel.getChildNodes().getLength(); i++) {
Node found = camel.getChildNodes().item(i);
String name = found.getNodeName();
if ("endpoint".equals(name)) {
endpoint = found;
}
}
if (endpoint != null) {
return endpoint;
}
Node last = null;
// if no endpoints then try to find cut-off according the XSD rules
for (int i = 0; i < camel.getChildNodes().getLength(); i++) {
Node found = camel.getChildNodes().item(i);
String name = found.getNodeName();
if ("dataFormats".equals(name) || "redeliveryPolicyProfile".equals(name)
|| "onException".equals(name) || "onCompletion".equals(name)
|| "intercept".equals(name) || "interceptFrom".equals(name)
|| "interceptSendToEndpoint".equals(name) || "restConfiguration".equals(name)
|| "rest".equals(name) || "route".equals(name)) {
return found;
}
if (found.getNodeType() == Node.ELEMENT_NODE) {
last = found;
}
}
return last;
}
/**
* Returns the mandatory String value of the given name
*
* @throws IllegalArgumentException if the value is not available in the given attribute map
*/
public static String mandatoryAttributeValue(Map attributeMap, String name) {
Object value = attributeMap.get(name);
if (value != null) {
String text = value.toString();
if (!Strings.isBlank(text)) {
return text;
}
}
throw new IllegalArgumentException("The attribute value '" + name + "' did not get passed on from the previous wizard page");
}
/**
* Returns the optional String value of the given name
*/
public static String optionalAttributeValue(Map attributeMap, String name) {
Object value = attributeMap.get(name);
if (value != null) {
String text = value.toString();
if (!Strings.isBlank(text)) {
return text;
}
}
return null;
}
}