// ============================================================================
//
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.repository.model.migration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.apache.oro.text.regex.Perl5Substitution;
import org.apache.oro.text.regex.Util;
import org.talend.commons.ui.runtime.exception.ExceptionHandler;
import org.talend.commons.utils.data.text.StringHelper;
import org.talend.core.language.ECodeLanguage;
import org.talend.core.model.components.ComponentUtilities;
import org.talend.core.model.components.ModifyComponentsAction;
import org.talend.core.model.components.conversions.IComponentConversion;
import org.talend.core.model.components.filters.IComponentFilter;
import org.talend.core.model.migration.AbstractJobMigrationTask;
import org.talend.core.model.process.EConnectionType;
import org.talend.core.model.properties.Item;
import org.talend.designer.core.model.utils.emf.talendfile.ConnectionType;
import org.talend.designer.core.model.utils.emf.talendfile.ElementParameterType;
import org.talend.designer.core.model.utils.emf.talendfile.ElementValueType;
import org.talend.designer.core.model.utils.emf.talendfile.NodeType;
import org.talend.designer.core.model.utils.emf.talendfile.ProcessType;
/**
* Use to replace .
*
*/
public class AddPerlRefArrayMigrationTask extends AbstractJobMigrationTask {
@Override
public ExecutionResult execute(Item item) {
try {
ProcessType processType = getProcessType(item);
if (getProject().getLanguage() == ECodeLanguage.JAVA
|| processType == null) {
return ExecutionResult.NOTHING_TO_DO;
} else {
List<String> namesList = new ArrayList<String>();
for (Object o : processType.getNode()) {
NodeType nt = (NodeType) o;
namesList.add(ComponentUtilities.getNodeUniqueName(nt));
}
for (Object o : processType.getConnection()) {
ConnectionType currentConnection = (ConnectionType) o;
int lineStyle = currentConnection.getLineStyle();
EConnectionType connectionType = EConnectionType.getTypeFromId(lineStyle);
if (connectionType.hasConnectionCategory(EConnectionType.FLOW)) {
namesList.add(currentConnection.getLabel());
}
}
final String[] namesArrays = namesList.toArray(new String[0]);
IComponentFilter filter1 = new IComponentFilter() {
/*
* (non-Javadoc)
*
* @see org.talend.core.model.components.filters.IComponentFilter#accept(org.talend.designer.core.model.utils.emf.talendfile.NodeType)
*/
public boolean accept(NodeType node) {
return true;
}
};
IComponentConversion componentConversion = new IComponentConversion() {
RefArraySyntaxReplacerForPerl parser = new RefArraySyntaxReplacerForPerl();
/*
* (non-Javadoc)
*
* @see org.talend.core.model.components.conversions.IComponentConversion#transform(org.talend.designer.core.model.utils.emf.talendfile.NodeType)
*/
public void transform(NodeType node) {
for (Object o : node.getElementParameter()) {
ElementParameterType pType = (ElementParameterType) o;
if (pType.getField().equals("TABLE")) { //$NON-NLS-1$
for (ElementValueType elementValue : (List<ElementValueType>) pType.getElementValue()) {
elementValue.getValue();
String value = elementValue.getValue();
if (value != null) {
String newValue = parser.processReplacementOperations(value, namesArrays);
elementValue.setValue(newValue);
}
}
} else {
String value = pType.getValue();
if (value != null) {
String newValue = parser.processReplacementOperations(value, namesArrays);
pType.setValue(newValue);
}
}
}
}
};
ModifyComponentsAction.searchAndModify(item, processType, filter1, Arrays.<IComponentConversion> asList(componentConversion));
return ExecutionResult.SUCCESS_WITH_ALERT;
}
} catch (Exception e) {
ExceptionHandler.process(e);
return ExecutionResult.FAILURE;
}
}
/**
*
* DOC amaumont AddPerlRefArrayPointer class global comment. Detailled comment
*/
public class RefArraySyntaxReplacerForPerl {
// private String expression;
private Perl5Matcher matcher = new Perl5Matcher();
private Perl5Compiler compiler = new Perl5Compiler();
private Set<TableEntryLocation> resultList = new HashSet<TableEntryLocation>();
private Pattern pattern;
private PatternMatcherInput patternMatcherInput;
private String locationPattern;
public RefArraySyntaxReplacerForPerl() {
super();
}
/**
* DOC amaumont Comment method "setRegexpPattern".
*
* @param regexpPattern
*/
public void setLocationPattern(String locationPattern) {
this.locationPattern = locationPattern;
}
public TableEntryLocation[] parseTableEntryLocations(String expression) {
resultList.clear();
if (expression != null) {
matcher.setMultiline(true);
if (patternMatcherInput == null) {
patternMatcherInput = new PatternMatcherInput(expression);
} else {
patternMatcherInput.setInput(expression);
}
recompilePatternIfNecessary(locationPattern);
while (matcher.contains(patternMatcherInput, pattern)) {
MatchResult matchResult = matcher.getMatch();
resultList.add(new TableEntryLocation(matchResult.group(1), matchResult.group(2)));
}
}
return resultList.toArray(new TableEntryLocation[0]);
}
private void recompilePatternIfNecessary(String regexpPattern) {
if (pattern == null || !regexpPattern.equals(pattern.getPattern())) {
try {
pattern = compiler.compile(regexpPattern);
} catch (MalformedPatternException e) {
throw new RuntimeException(e);
}
}
}
public String processReplacementOperations(String expression, String[] tableNames) {
String returnedExpression = expression;
for (int i = 0; i < tableNames.length; i++) {
String connectionName = tableNames[i];
recompilePatternIfNecessary(StringHelper.replacePrms("\\$[\\s\\r\\n]*({0})[\\s\\r\\n]*\\[", //$NON-NLS-1$
new Object[] { connectionName }));
if (returnedExpression != null) {
matcher.setMultiline(true);
Perl5Substitution substitution = new Perl5Substitution("\\$" + "$1->" //$NON-NLS-1$ //$NON-NLS-2$
+ "[", Perl5Substitution.INTERPOLATE_ALL); //$NON-NLS-1$
returnedExpression = Util.substitute(matcher, pattern, substitution, returnedExpression, Util.SUBSTITUTE_ALL);
}
recompilePatternIfNecessary(StringHelper.replacePrms("@[\\s\\r\\n]*({0})\\b", new Object[] { connectionName })); //$NON-NLS-1$
if (returnedExpression != null) {
matcher.setMultiline(true);
Perl5Substitution substitution = new Perl5Substitution("@\\$" + "$1" //$NON-NLS-1$ //$NON-NLS-2$
, Perl5Substitution.INTERPOLATE_ALL);
returnedExpression = Util.substitute(matcher, pattern, substitution, returnedExpression, Util.SUBSTITUTE_ALL);
}
}
return returnedExpression;
}
}
/**
*
* DOC amaumont AddPerlRefArrayPointer class global comment. Detailled comment
*/
public class TableEntryLocation {
public String tableName;
public String columnName;
public TableEntryLocation() {
super();
}
/**
* DOC amaumont Couple constructor comment.
*
* @param tableName
* @param columnName
*/
public TableEntryLocation(String tableName, String columnName) {
this.tableName = tableName;
this.columnName = columnName;
}
/**
* DOC amaumont Couple constructor comment.
*
* @param tableName
* @param columnName
*/
public TableEntryLocation(TableEntryLocation tableEntryLocation) {
this.tableName = tableEntryLocation.tableName;
this.columnName = tableEntryLocation.columnName;
}
@Override
public String toString() {
return "{tableName=" + this.tableName + ", columnName=" + this.columnName + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.columnName == null) ? 0 : this.columnName.hashCode());
result = prime * result + ((this.tableName == null) ? 0 : this.tableName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TableEntryLocation other = (TableEntryLocation) obj;
if (this.columnName == null) {
if (other.columnName != null) {
return false;
}
} else if (!this.columnName.equals(other.columnName)) {
return false;
}
if (this.tableName == null) {
if (other.tableName != null) {
return false;
}
} else if (!this.tableName.equals(other.tableName)) {
return false;
}
return true;
}
}
public Date getOrder() {
GregorianCalendar gc = new GregorianCalendar(2008, 2, 17, 12, 0, 0);
return gc.getTime();
}
}