Subversion Repositories XServices

Rev

Rev 169 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 169 Rev 170
1
/*
1
/*
2
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
2
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
3
 *
3
 *
4
 *   Licensed under the Apache License, Version 2.0 (the "License");
4
 *   Licensed under the Apache License, Version 2.0 (the "License");
5
 *   you may not use this file except in compliance with the License.
5
 *   you may not use this file except in compliance with the License.
6
 *   You may obtain a copy of the License at
6
 *   You may obtain a copy of the License at
7
 *
7
 *
8
 *       http://www.apache.org/licenses/LICENSE-2.0
8
 *       http://www.apache.org/licenses/LICENSE-2.0
9
 *
9
 *
10
 *   Unless required by applicable law or agreed to in writing, software
10
 *   Unless required by applicable law or agreed to in writing, software
11
 *   distributed under the License is distributed on an "AS IS" BASIS,
11
 *   distributed under the License is distributed on an "AS IS" BASIS,
12
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *   See the License for the specific language governing permissions and
13
 *   See the License for the specific language governing permissions and
14
 *   limitations under the License.
14
 *   limitations under the License.
15
 */
15
 */
16
package net.brutex.emitter;
16
package net.brutex.emitter;
17
 
17
 
18
import java.io.File;
18
import java.io.File;
19
import java.io.FileInputStream;
19
import java.io.FileInputStream;
20
import java.io.FileNotFoundException;
20
import java.io.FileNotFoundException;
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.io.StringWriter;
22
import java.io.StringWriter;
23
import java.math.BigInteger;
23
import java.math.BigInteger;
24
import java.net.MalformedURLException;
24
import java.net.MalformedURLException;
25
import java.text.SimpleDateFormat;
25
import java.text.SimpleDateFormat;
26
import java.util.ArrayList;
26
import java.util.ArrayList;
27
import java.util.HashMap;
27
import java.util.HashMap;
28
import java.util.List;
28
import java.util.List;
29
import java.util.Map;
29
import java.util.Map;
30
 
30
 
31
import javax.xml.stream.XMLStreamException;
31
import javax.xml.stream.XMLStreamException;
-
 
32
 
32
import net.brutex.emitter.util.EmitterUtil;
33
import net.brutex.emitter.util.EmitterUtil;
-
 
34
import net.brutex.emitter.util.PasswordEncrypter;
33
import net.brutex.sbm.sbmappservices72.AEWebservicesFaultFault;
35
import net.brutex.sbm.sbmappservices72.AEWebservicesFaultFault;
34
import net.brutex.sbm.sbmappservices72.Sbmappservices72PortType;
36
import net.brutex.sbm.sbmappservices72.Sbmappservices72PortType;
35
import net.brutex.sbm.sbmappservices72.api.Auth;
37
import net.brutex.sbm.sbmappservices72.api.Auth;
36
import net.brutex.sbm.sbmappservices72.api.MultipleResponseItemOptions;
38
import net.brutex.sbm.sbmappservices72.api.MultipleResponseItemOptions;
37
import net.brutex.sbm.sbmappservices72.api.ObjectFactory;
39
import net.brutex.sbm.sbmappservices72.api.ObjectFactory;
38
import net.brutex.sbm.sbmappservices72.api.SectionsOption;
40
import net.brutex.sbm.sbmappservices72.api.SectionsOption;
39
import net.brutex.sbm.sbmappservices72.api.TTItemList;
41
import net.brutex.sbm.sbmappservices72.api.TTItemList;
40
import net.brutex.sbm.sbmappservices72.api.TableIdentifier;
42
import net.brutex.sbm.sbmappservices72.api.TableIdentifier;
41
import net.brutex.svn.SVNAdminCommand;
43
import net.brutex.svn.SVNAdminCommand;
42
import net.brutex.svn.SVNAdminExecutor;
44
import net.brutex.svn.SVNAdminExecutor;
43
import net.brutex.svn.SVNCommitInfo;
45
import net.brutex.svn.SVNCommitInfo;
44
import net.brutex.svn.SVNLookExecutor;
46
import net.brutex.svn.SVNLookExecutor;
45
 
47
 
46
import org.apache.axiom.om.OMAbstractFactory;
48
import org.apache.axiom.om.OMAbstractFactory;
47
import org.apache.axiom.om.OMComment;
49
import org.apache.axiom.om.OMComment;
48
import org.apache.axiom.om.OMElement;
50
import org.apache.axiom.om.OMElement;
49
import org.apache.axiom.om.OMFactory;
51
import org.apache.axiom.om.OMFactory;
50
import org.apache.axiom.om.OMNamespace;
52
import org.apache.axiom.om.OMNamespace;
51
import org.apache.axiom.om.OMNode;
53
import org.apache.axiom.om.OMNode;
52
import org.apache.axiom.om.OMText;
54
import org.apache.axiom.om.OMText;
53
import org.apache.axiom.om.OMXMLBuilderFactory;
55
import org.apache.axiom.om.OMXMLBuilderFactory;
54
import org.apache.axiom.om.xpath.AXIOMXPath;
56
import org.apache.axiom.om.xpath.AXIOMXPath;
55
import org.apache.commons.cli.CommandLine;
57
import org.apache.commons.cli.CommandLine;
56
import org.apache.commons.cli.CommandLineParser;
58
import org.apache.commons.cli.CommandLineParser;
57
import org.apache.commons.cli.HelpFormatter;
59
import org.apache.commons.cli.HelpFormatter;
58
import org.apache.commons.cli.Option;
60
import org.apache.commons.cli.Option;
59
import org.apache.commons.cli.OptionBuilder;
61
import org.apache.commons.cli.OptionBuilder;
60
import org.apache.commons.cli.Options;
62
import org.apache.commons.cli.Options;
61
import org.apache.commons.cli.BasicParser;
63
import org.apache.commons.cli.BasicParser;
62
import org.apache.commons.cli.ParseException;
64
import org.apache.commons.cli.ParseException;
63
import org.apache.commons.configuration.Configuration;
65
import org.apache.commons.configuration.Configuration;
64
import org.apache.commons.configuration.ConfigurationException;
66
import org.apache.commons.configuration.ConfigurationException;
65
import org.apache.commons.configuration.PropertiesConfiguration;
67
import org.apache.commons.configuration.PropertiesConfiguration;
66
import org.apache.cxf.endpoint.Client;
68
import org.apache.cxf.endpoint.Client;
67
import org.apache.cxf.frontend.ClientProxy;
69
import org.apache.cxf.frontend.ClientProxy;
68
import org.apache.cxf.interceptor.LoggingInInterceptor;
70
import org.apache.cxf.interceptor.LoggingInInterceptor;
69
import org.apache.cxf.interceptor.LoggingOutInterceptor;
71
import org.apache.cxf.interceptor.LoggingOutInterceptor;
70
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
72
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
71
import org.apache.http.client.ClientProtocolException;
73
import org.apache.http.client.ClientProtocolException;
72
import org.apache.log4j.Logger;
74
import org.apache.log4j.Logger;
73
import org.jaxen.JaxenException;
75
import org.jaxen.JaxenException;
74
 
76
 
75
 
77
 
76
/**
78
/**
77
 * The Class ALFEmitter.
79
 * The Class ALFEmitter.
78
 *
80
 *
79
 * @author Brian Rosenberger, bru(at)brutex.de
81
 * @author Brian Rosenberger, bru(at)brutex.de
80
 * @since 0.1
82
 * @since 0.1
81
 */
83
 */
82
public class ALFEmitter {
84
public class ALFEmitter {
83
	
85
	
84
	public static final String VERSION = "0.1";
86
	public static final String VERSION = "0.1";
85
	private static Logger logger = Logger.getRootLogger();
87
	private static Logger logger = Logger.getRootLogger();
86
	
88
	
87
	//
89
	//
88
	// Keys to read from the configuration file.
90
	// Keys to read from the configuration file.
89
	//
91
	//
90
	private static final String OPTION_SVNLOOK = "svnlook";
92
	private static final String OPTION_SVNLOOK = "svnlook";
91
	private static final String OPTION_SVNADMIN = "svnadmin";
93
	private static final String OPTION_SVNADMIN = "svnadmin";
92
	private static final String OPTION_LOCALE = "env.LANG";
94
	private static final String OPTION_LOCALE = "env.LANG";
93
	private static final String OPTION_ENCODING = "env.encoding";
95
	private static final String OPTION_ENCODING = "env.encoding";
94
	private static final String OPTION_ISSUEPATTERN = "issuepattern";
96
	private static final String OPTION_ISSUEPATTERN = "issuepattern";
95
	
97
	
96
	private static final String OPTION_EVENTTEMPLATE = "eventtemplate";
98
	private static final String OPTION_EVENTTEMPLATE = "eventtemplate";
97
	private static final String OPTION_EVENTNAMESPACE = "eventnamespace";
99
	private static final String OPTION_EVENTNAMESPACE = "eventnamespace";
98
	private static final String OPTION_EVENTMANAGER_URL = "eventmanager";
100
	private static final String OPTION_EVENTMANAGER_URL = "eventmanager";
99
	private static final String OPTION_EVENTMANAGER_USER = "eventmanager.user";
101
	private static final String OPTION_EVENTMANAGER_USER = "eventmanager.user";
100
	private static final String OPTION_EVENTMANAGER_PASSWORD = "eventmanager.password";
102
	private static final String OPTION_EVENTMANAGER_PASSWORD = "eventmanager.password";
-
 
103
	private static final String OPTION_EVENTMANAGER_ENCRYPTED = "eventmanager.encrypted";
101
	
104
	
102
	private static final String OPTION_SBM_ENDPOINT = "sbmappservices72";
105
	private static final String OPTION_SBM_ENDPOINT = "sbmappservices72";
103
	private static final String OPTION_SBM_USER = "sbmuser";
106
	private static final String OPTION_SBM_USER = "sbmuser";
104
	private static final String OPTION_SBM_PASSWORD = "sbmpassword";
107
	private static final String OPTION_SBM_PASSWORD = "sbmpassword";
-
 
108
	private static final String OPTION_SBM_ENCRYPTED = "sbmencrypted";
105
	private static final String OPTION_SBM_TABLE = "querytable";
109
	private static final String OPTION_SBM_TABLE = "querytable";
106
	private static final String OPTION_SBM_QUERY = "query";
110
	private static final String OPTION_SBM_QUERY = "query";
107
 
111
 
108
	private static final String OPTION_MARKER_LOGMESSAGE = "marker.logmessage";
112
	private static final String OPTION_MARKER_LOGMESSAGE = "marker.logmessage";
109
	private static final String OPTION_MARKER_AUTHOR = "marker.author";
113
	private static final String OPTION_MARKER_AUTHOR = "marker.author";
110
	private static final String OPTION_MARKER_REVISION = "marker.revision";
114
	private static final String OPTION_MARKER_REVISION = "marker.revision";
111
	private static final String OPTION_MARKER_ADDEDFILES = "marker.addedfiles";
115
	private static final String OPTION_MARKER_ADDEDFILES = "marker.addedfiles";
112
	private static final String OPTION_MARKER_DELETEDFILES = "marker.deletedfiles";
116
	private static final String OPTION_MARKER_DELETEDFILES = "marker.deletedfiles";
113
	private static final String OPTION_MARKER_CHANGEDFILES = "marker.changedfiles";
117
	private static final String OPTION_MARKER_CHANGEDFILES = "marker.changedfiles";
114
	private static final String OPTION_MARKER_ISSUES = "marker.issues";
118
	private static final String OPTION_MARKER_ISSUES = "marker.issues";
115
	private static final String OPTION_MARKER_INTERNALISSUES = "marker.internalissues";
119
	private static final String OPTION_MARKER_INTERNALISSUES = "marker.internalissues";
116
	private static final String OPTION_REMOVE_ISSUES_FROM_COMMIT = "removeissuesfromcommit";
120
	private static final String OPTION_REMOVE_ISSUES_FROM_COMMIT = "removeissuesfromcommit";
117
	
121
	
118
	private static final String OPTION_IS_SOAPENABLED = "isSoapEnabled";
122
	private static final String OPTION_IS_SOAPENABLED = "isSoapEnabled";
119
	private static final String OPTION_IS_DROPENABLED = "isDropResponse";
123
	private static final String OPTION_IS_DROPENABLED = "isDropResponse";
120
	private static final String OPTION_IS_FORCEFAILENABLED = "forcefail";
124
	private static final String OPTION_IS_FORCEFAILENABLED = "forcefail";
121
	private static final String OPTION_IS_VERIFICATIONENABLED = "isWithVerification";
125
	private static final String OPTION_IS_VERIFICATIONENABLED = "isWithVerification";
122
	private static final String OPTION_IS_UPDATECOMMITMESSAGE = "isWithMessageUpdate";
126
	private static final String OPTION_IS_UPDATECOMMITMESSAGE = "isWithMessageUpdate";
123
	private static final String OPTION_IS_WSTRACE = "trace";
127
	private static final String OPTION_IS_WSTRACE = "trace";
124
	private static final String OPTION_IS_XMLPROCESSINGENABLED = "isXmlProcessingEnabled";
128
	private static final String OPTION_IS_XMLPROCESSINGENABLED = "isXmlProcessingEnabled";
125
 
129
 
126
	//
130
	//
127
	// Command line parameters
131
	// Command line parameters
128
	//
132
	//
129
	private static final String PARAM_REPOS = "repos";
133
	private static final String PARAM_REPOS = "repos";
130
	private static final String PARAM_TXN = "txn";
134
	private static final String PARAM_TXN = "txn";
131
	private static final String PARAM_REV = "rev";
135
	private static final String PARAM_REV = "rev";
132
	private static final String PARAM_CONFIG = "conf";
136
	private static final String PARAM_CONFIG = "conf";
133
	
137
	
134
	//
138
	//
135
	//
-
 
136
	//
-
 
137
	private static final String CACHE_SBMPORT = "sbmappservices72";
-
 
138
	
-
 
139
	//
-
 
140
	// Member variables
139
	// Member variables
141
	//
140
	//
142
	private final String repos;
141
	private final String repos;
143
	private final String txn;
142
	private final String txn;
144
	private final String rev;
143
	private final String rev;
145
	private SVNCommitInfo info;
144
	private SVNCommitInfo info;
146
	private OMElement template = null;
145
	private OMElement template = null;
147
	private Configuration config;
146
	private Configuration config;
148
	private String nss = null;
147
	private String nss = null;
149
	private final long startTime;
148
	private final long startTime;
150
	
149
	
151
	//Member for SBM endpoint configuration
150
	//Member for SBM endpoint configuration
152
	private final String endpoint;
151
	private final String endpoint;
153
	private final String sbm_user;
152
	private final String sbm_user;
154
	private final String sbm_pass;
153
	private String sbm_pass;
155
	private final String querytable;
154
	private final String querytable;
156
	private final String query;
155
	private final String query;
157
 
156
 
158
	
157
	
159
	private final List<String> internalissues = new ArrayList<String>();
158
	private final List<String> internalissues = new ArrayList<String>();
160
	//SBM IssueTypePrefix+IssueId, Title
159
	//SBM IssueTypePrefix+IssueId, Title
161
	private final Map<String, String> issues_titles = new HashMap<String, String>();
160
	private final Map<String, String> issues_titles = new HashMap<String, String>();
162
	
161
	
163
	/**
162
	/**
164
	 * The main method.
163
	 * The main method.
165
	 *
164
	 *
166
	 * @param args the arguments
165
	 * @param args the arguments
167
	 */
166
	 */
168
	public static void main(String[] args) {
167
	public static void main(String[] args) {
169
		long startTime = System.currentTimeMillis();
168
		long startTime = System.currentTimeMillis();
170
		CommandLineParser parser = new BasicParser();
169
		CommandLineParser parser = new BasicParser();
171
		CommandLine cmd = null;
170
		CommandLine cmd = null;
172
		try {
171
		try {
173
			cmd = parser.parse( getOptions(), args);
172
			cmd = parser.parse( getOptions(), args);
174
		} catch (ParseException e1) {
173
		} catch (ParseException e1) {
175
			logger.error(e1.getMessage());
174
			logger.error(e1.getMessage());
176
			printHelp();
175
			printHelp();
177
			System.exit(1);
176
			System.exit(1);
178
		}
177
		}
179
		try {
178
		try {
180
			ALFEmitter emitter = new ALFEmitter(cmd, startTime);
179
			ALFEmitter emitter = new ALFEmitter(cmd, startTime);
181
		} catch (ConfigurationException e) {
180
		} catch (ConfigurationException e) {
182
			System.exit(1);
181
			System.exit(1);
183
		} catch (MalformedURLException e) {
182
		} catch (MalformedURLException e) {
184
			logger.error("Could not find/ load wsdl url.", e);
183
			logger.error("Could not find/ load wsdl url.", e);
185
			System.exit(1);
184
			System.exit(1);
186
		}
185
		}
187
		long endTime = System.currentTimeMillis();
186
		long endTime = System.currentTimeMillis();
188
		logger.debug("Total execution took '"+(endTime-startTime)+"' milliseconds.");
187
		logger.debug("Total execution took '"+(endTime-startTime)+"' milliseconds.");
189
		System.exit(0);
188
		System.exit(0);
190
	}
189
	}
191
	
190
	
192
	/**
191
	/**
193
	 * Read a configuration parameter from the config file
192
	 * Read a configuration parameter from the config file
194
	 * Creates log messages according to parameters.
193
	 * Creates log messages according to parameters.
195
	 * 
194
	 * 
196
	 * @param key				property name
195
	 * @param key				property name
197
	 * @param defaultValue		default value or null
196
	 * @param defaultValue		default value or null
198
	 * @param isRequired		wether or not this is a required option
197
	 * @param isRequired		whether or not this is a required option
199
	 * @param logmessage		optional log message (or null)
198
	 * @param logmessage		optional log message (or null)
200
	 * @return					property value
199
	 * @return					property value
201
	 * @throws ConfigurationException
200
	 * @throws ConfigurationException
202
	 */
201
	 */
203
	private Object readConfProperty(String key, Object defaultValue, boolean isRequired, PropertyType type, String logmessage) throws ConfigurationException {
202
	private Object readConfProperty(String key, Object defaultValue, boolean isRequired, PropertyType type, String logmessage) throws ConfigurationException {
204
		Object value = null;
203
		Object value = null;
205
		switch (type) {
204
		switch (type) {
206
		case BOOLEAN:
205
		case BOOLEAN:
207
			value = config.getBoolean(key, (Boolean) defaultValue);
206
			value = config.getBoolean(key, (Boolean) defaultValue);
208
			break;
207
			break;
209
		case STRINGARRAY:
208
		case STRINGARRAY:
210
			value = config.getStringArray(key);
209
			value = config.getStringArray(key);
211
			defaultValue = null;
210
			defaultValue = null;
212
			break;
211
			break;
213
 
212
 
214
		default:
213
		default:
215
			value = config.getString(key, (String) defaultValue);
214
			value = config.getString(key, (String) defaultValue);
216
			break;
215
			break;
217
		}
216
		}
218
		 
217
		 
219
		if(isRequired && value == null) {
218
		if(isRequired && value == null) {
220
			//required property	
219
			//required property	
221
			if(defaultValue == null) {
220
			if(defaultValue == null) {
222
				//No value, no default
221
				//No value, no default
223
				String s = String.format("Could not load a value for the key '%s' from the configuration file. This is a required property without a default.", key);
222
				String s = String.format("Could not load a value for the key '%s' from the configuration file. This is a required property without a default.", key);
224
				logger.error(s);
223
				logger.error(s);
225
				throw new ConfigurationException(s);
224
				throw new ConfigurationException(s);
226
			}
225
			}
227
			if(defaultValue!=null) {
226
			if(defaultValue!=null) {
228
				//No value, but default
227
				//No value, but default
229
				logger.debug(String.format("Using property value '%s' for key '%s'. This is the default value. The property is required.", value, key));
228
				logger.debug(String.format("Using property value '%s' for key '%s'. This is the default value. The property is required.", value, key));
230
			}
229
			}
231
		} 
230
		} 
232
		if( (! isRequired) && value == null) {
231
		if( (! isRequired) && value == null) {
233
			//not required
232
			//not required
234
			if(value == null && defaultValue == null) {
233
			if(value == null && defaultValue == null) {
235
				//No value, no default
234
				//No value, no default
236
				String s = String.format("Could not load a value for the key '%s' from the configuration file. This property has no default, but it is optional anyway.", key);
235
				String s = String.format("Could not load a value for the key '%s' from the configuration file. This property has no default, but it is optional anyway.", key);
237
				logger.warn(s);
236
				logger.warn(s);
238
			}
237
			}
239
			if(value == null && defaultValue!=null) {
238
			if(value == null && defaultValue!=null) {
240
				//No value, but default
239
				//No value, but default
241
				logger.debug(String.format("Using property value '%s' for key '%s'. This is the default value. The property is optional.", value, key));				
240
				logger.debug(String.format("Using property value '%s' for key '%s'. This is the default value. The property is optional.", value, key));				
242
			}
241
			}
243
		}
242
		}
244
		if(logmessage==null) logmessage="";
243
		if(logmessage==null) logmessage="";
245
		if(key.contains("password") && value!=null ) {
244
		if(key.contains("password") && value!=null ) {
246
			logger.debug(String.format("Using property value '%s' for key '%s'. %s", "******", key, logmessage));
245
			logger.debug(String.format("Using property value '%s' for key '%s'. %s", "******", key, logmessage));
247
		} else {
246
		} else {
248
			if(value!=null) logger.debug(String.format("Using property value '%s' for key '%s'. %s", value, key, logmessage));
247
			if(value!=null) logger.debug(String.format("Using property value '%s' for key '%s'. %s", value, key, logmessage));
249
		}
248
		}
250
		return value;
249
		return value;
251
	}
250
	}
252
	
251
	
253
	
252
	
254
	private String readConfPropertyAsString(String key, String defaultValue, boolean isRequired, String logmessage) throws ConfigurationException {
253
	private String readConfPropertyAsString(String key, String defaultValue, boolean isRequired, String logmessage) throws ConfigurationException {
255
		return (String) readConfProperty(key, defaultValue, isRequired, PropertyType.STRING, logmessage);
254
		return (String) readConfProperty(key, defaultValue, isRequired, PropertyType.STRING, logmessage);
256
	}
255
	}
257
	private String[] readConfPropertyAsStringArray(String key, boolean isRequired, String logmessage) throws ConfigurationException {
256
	private String[] readConfPropertyAsStringArray(String key, boolean isRequired, String logmessage) throws ConfigurationException {
258
		return (String[]) readConfProperty(key, null, isRequired, PropertyType.STRINGARRAY, logmessage);
257
		return (String[]) readConfProperty(key, null, isRequired, PropertyType.STRINGARRAY, logmessage);
259
	}
258
	}
260
	private boolean readConfPropertyAsBoolean(String key, boolean defaultValue, boolean isRequired, String logmessage) throws ConfigurationException {
259
	private boolean readConfPropertyAsBoolean(String key, boolean defaultValue, boolean isRequired, String logmessage) throws ConfigurationException {
261
		Boolean b =  (Boolean) readConfProperty(key, defaultValue, isRequired, PropertyType.BOOLEAN, logmessage);
260
		Boolean b =  (Boolean) readConfProperty(key, defaultValue, isRequired, PropertyType.BOOLEAN, logmessage);
262
		return b.booleanValue();
261
		return b.booleanValue();
263
	}
262
	}
264
		
263
		
265
	private ALFEmitter(CommandLine cmd, long startTime) throws ConfigurationException, MalformedURLException {
264
	private ALFEmitter(CommandLine cmd, long startTime) throws ConfigurationException, MalformedURLException {
266
		this.startTime = startTime;
265
		this.startTime = startTime;
267
		repos = cmd.getOptionValue(PARAM_REPOS);
266
		repos = cmd.getOptionValue(PARAM_REPOS);
268
		txn = cmd.getOptionValue(PARAM_TXN);
267
		txn = cmd.getOptionValue(PARAM_TXN);
269
		rev = cmd.getOptionValue(PARAM_REV);
268
		rev = cmd.getOptionValue(PARAM_REV);
270
		String config_file = cmd.getOptionValue(PARAM_CONFIG, "emitter.properties");
269
		String config_file = cmd.getOptionValue(PARAM_CONFIG, "emitter.properties");
271
		EmitterUtil.verifyFile(config_file, false, false);
270
		EmitterUtil.verifyFile(config_file, false, false);
272
 
271
 
273
		logger.debug(String.format("Using REPOS='%s' and TXN='%s'.", repos, txn));
272
		logger.debug(String.format("Using REPOS='%s' and TXN='%s'.", repos, txn));
274
	
273
	
275
		config = null;
274
		config = null;
276
		try {
275
		try {
277
			config = new PropertiesConfiguration(config_file);
276
			config = new PropertiesConfiguration(config_file);
278
		} catch (ConfigurationException e) {
277
		} catch (ConfigurationException e) {
279
			logger.error("Could not find/ load '"+config_file+"' file.", e);
278
			logger.error("Could not find/ load '"+config_file+"' file.", e);
280
			this.exit(1);
279
			this.exit(1);
281
		}
280
		}
282
		
281
		
283
		/*
282
		/*
284
		 * Load Properties from Configuration file
283
		 * Load Properties from Configuration file
285
		 */
284
		 */
286
		//it might be interesting to look into SVNKit
285
		//it might be interesting to look into SVNKit
287
		//for a pure Java implementation in future
286
		//for a pure Java implementation in future
288
			final String svnlook			=	readConfPropertyAsString(OPTION_SVNLOOK, null, true, null);
287
			final String svnlook			=	readConfPropertyAsString(OPTION_SVNLOOK, null, true, null);
289
			EmitterUtil.verifyFile(svnlook, false, true);
288
			EmitterUtil.verifyFile(svnlook, false, true);
290
			final String locale				=	readConfPropertyAsString(OPTION_LOCALE, "de_DE.UTF-8", true, null);
289
			final String locale				=	readConfPropertyAsString(OPTION_LOCALE, "de_DE.UTF-8", true, null);
291
			final String encoding			=	readConfPropertyAsString(OPTION_ENCODING, "UTF-8", true, "Note that this should match your selected '"+OPTION_LOCALE+"'.");
290
			final String encoding			=	readConfPropertyAsString(OPTION_ENCODING, "UTF-8", true, "Note that this should match your selected '"+OPTION_LOCALE+"'.");
292
			
291
			
293
			// Issue Id RegEx to parse commit message
292
			// Issue Id RegEx to parse commit message
294
			final String[] issuepatterns = readConfPropertyAsStringArray(OPTION_ISSUEPATTERN, false, null);
293
			final String[] issuepatterns = readConfPropertyAsStringArray(OPTION_ISSUEPATTERN, false, null);
295
			StringBuilder sb = new StringBuilder(); for(String s : issuepatterns) sb.append(s);
294
			StringBuilder sb = new StringBuilder(); for(String s : issuepatterns) sb.append(s);
296
			logger.debug(String.format("Using issue id patterns: '%s'.", sb.toString()));
295
			logger.debug(String.format("Using issue id patterns: '%s'.", sb.toString()));
297
			
296
			
298
			// Flags to indicate what should be done
297
			// Flags to indicate what should be done
299
			final boolean isSoapEnabled 	= readConfPropertyAsBoolean(OPTION_IS_SOAPENABLED, true, true, null);
298
			final boolean isSoapEnabled 	= readConfPropertyAsBoolean(OPTION_IS_SOAPENABLED, true, true, null);
300
			final boolean isXmlProcessingEnabled 	= readConfPropertyAsBoolean(OPTION_IS_XMLPROCESSINGENABLED, true, true, null);
299
			final boolean isXmlProcessingEnabled 	= readConfPropertyAsBoolean(OPTION_IS_XMLPROCESSINGENABLED, true, true, null);
301
			final boolean isWithVerification= readConfPropertyAsBoolean(OPTION_IS_VERIFICATIONENABLED, false, true, null);
300
			final boolean isWithVerification= readConfPropertyAsBoolean(OPTION_IS_VERIFICATIONENABLED, false, true, null);
302
			final boolean isRemoveIssues	= readConfPropertyAsBoolean(OPTION_REMOVE_ISSUES_FROM_COMMIT, false, true, "");
301
			final boolean isRemoveIssues	= readConfPropertyAsBoolean(OPTION_REMOVE_ISSUES_FROM_COMMIT, false, true, "");
303
			final boolean isWithCommitUpdate= readConfPropertyAsBoolean(OPTION_IS_UPDATECOMMITMESSAGE, false, true, "");
302
			final boolean isWithCommitUpdate= readConfPropertyAsBoolean(OPTION_IS_UPDATECOMMITMESSAGE, false, true, "");
304
			
303
			
305
			/*
304
			/*
306
			 * SVNLook phase
305
			 * SVNLook phase
307
			 * Use svnlook to obtain information from SVN
306
			 * Use svnlook to obtain information from SVN
308
			 */
307
			 */
309
			SVNLookExecutor exec = new SVNLookExecutor(new File(svnlook), repos);
308
			SVNLookExecutor exec = new SVNLookExecutor(new File(svnlook), repos);
310
			if(cmd.hasOption(PARAM_TXN)) exec.setTXN(txn);
309
			if(cmd.hasOption(PARAM_TXN)) exec.setTXN(txn);
311
			if(cmd.hasOption(PARAM_REV)) exec.setRev(rev);
310
			if(cmd.hasOption(PARAM_REV)) exec.setRev(rev);
312
			exec.setEncoding(encoding);
311
			exec.setEncoding(encoding);
313
			exec.setLocale(locale);
312
			exec.setLocale(locale);
314
			
313
			
315
			info = exec.getCommitInfo();			
314
			info = exec.getCommitInfo();			
316
			info.parseIssues(issuepatterns, isRemoveIssues);
315
			info.parseIssues(issuepatterns, isRemoveIssues);
317
			
316
			
318
			logger.debug("SVNCommitInfo author: "+ info.getAuthor());
317
			logger.debug("SVNCommitInfo author: "+ info.getAuthor());
319
			SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
318
			SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
320
			String datestring = f.format(info.getDate());
319
			String datestring = f.format(info.getDate());
321
			datestring= datestring.substring(0, 26) + ":" + datestring.substring(26); //hack into ISO 8601 format
320
			datestring= datestring.substring(0, 26) + ":" + datestring.substring(26); //hack into ISO 8601 format
322
			logger.debug("SVNCommitInfo date: "+ datestring);
321
			logger.debug("SVNCommitInfo date: "+ datestring);
323
			logger.debug("SVNCommitInfo log message: "+ info.getLogmessage());
322
			logger.debug("SVNCommitInfo log message: "+ info.getLogmessage());
324
			logger.debug("SVNCommitInfo file list: "+ info.getChangeFileListAsString());
323
			logger.debug("SVNCommitInfo file list: "+ info.getChangeFileListAsString());
325
			
324
			
326
			/*
325
			/*
327
			 * Verification phase
326
			 * Verification phase
328
			 */
327
			 */
329
			boolean isTrace = false;
328
			boolean isTrace = false;
330
			if(isWithVerification) {
329
			if(isWithVerification) {
-
 
330
				boolean isEncrypted;
-
 
331
				isEncrypted					=	readConfPropertyAsBoolean(OPTION_SBM_ENCRYPTED, false, false, null);
331
				sbm_user 					= 	readConfPropertyAsString(OPTION_SBM_USER, null, true, null);
332
				sbm_user 					= 	readConfPropertyAsString(OPTION_SBM_USER, null, true, null);
332
				sbm_pass 					= 	readConfPropertyAsString(OPTION_SBM_PASSWORD, null, false, null);
333
				sbm_pass 					= 	readConfPropertyAsString(OPTION_SBM_PASSWORD, null, false, null);
-
 
334
				if(isEncrypted) sbm_pass = PasswordEncrypter.decrypt(sbm_pass);
333
				endpoint					= 	readConfPropertyAsString(OPTION_SBM_ENDPOINT, "http://localhost/gsoap/gsoap_ssl.dll?sbmappservices72", true, null);
335
				endpoint					= 	readConfPropertyAsString(OPTION_SBM_ENDPOINT, "http://localhost/gsoap/gsoap_ssl.dll?sbmappservices72", true, null);
334
				querytable					= 	readConfPropertyAsString(OPTION_SBM_TABLE, null, true, null);
336
				querytable					= 	readConfPropertyAsString(OPTION_SBM_TABLE, null, true, null);
335
				query						= 	readConfPropertyAsString(OPTION_SBM_QUERY, null, false, null);
337
				query						= 	readConfPropertyAsString(OPTION_SBM_QUERY, null, false, null);
336
				isTrace						=	readConfPropertyAsBoolean(OPTION_IS_WSTRACE, false, true, null);
338
				isTrace						=	readConfPropertyAsBoolean(OPTION_IS_WSTRACE, false, true, null);
337
			
339
			
338
				logger.debug(String.format("Starting verification for '%s' issues in the list.", info.getIssues().size()));
340
				logger.debug(String.format("Starting verification for '%s' issues in the list.", info.getIssues().size()));
339
				boolean isOK = verify(info.getIssues(), isTrace);
341
				boolean isOK = verify(info.getIssues(), isTrace);
340
				if(! isOK ) {
342
				if(! isOK ) {
341
					logger.error("Verification of issue failed. No matching issue was found.");
343
					logger.error("Verification of issue failed. No matching issue was found.");
342
					this.exit(1);
344
					this.exit(1);
343
				}
345
				}
344
			} else {
346
			} else {
345
				sbm_user = null; sbm_pass=null; endpoint=null; querytable=null; query=null;
347
				sbm_user = null; sbm_pass=null; endpoint=null; querytable=null; query=null;
346
			}
348
			}
347
 
349
 
348
			/*
350
			/*
349
			 * Modify original commit message
351
			 * Modify original commit message
350
			 * using svnadmin command
352
			 * using svnadmin command
351
			 */
353
			 */
352
			if(isWithCommitUpdate) {
354
			if(isWithCommitUpdate) {
353
				String svnadmin = readConfPropertyAsString(OPTION_SVNADMIN, null, true, null);
355
				String svnadmin = readConfPropertyAsString(OPTION_SVNADMIN, null, true, null);
354
				EmitterUtil.verifyFile(svnadmin, false, true);
356
				EmitterUtil.verifyFile(svnadmin, false, true);
355
				/* If verification was turned on, we do already have the titles
357
				/* If verification was turned on, we do already have the titles
356
				 * so only try to load the items when verification was off
358
				 * so only try to load the items when verification was off
357
				 */
359
				 */
358
				if(! isWithVerification) {
360
				if(! isWithVerification) {
359
					verify(info.getIssues(), isTrace);
361
					verify(info.getIssues(), isTrace);
360
				}
362
				}
361
				/* Append associated items information and change log message */
363
				/* Append associated items information and change log message */
362
				StringBuffer newmessage = new StringBuffer();
364
				StringBuffer newmessage = new StringBuffer();
363
				newmessage.append(info.getLogmessage());
365
				newmessage.append(info.getLogmessage());
364
				newmessage.append("\n\n Associated SBM items:\n");
366
				newmessage.append("\n\n Associated SBM items:\n");
365
				for(String s : issues_titles.keySet()) {
367
				for(String s : issues_titles.keySet()) {
366
					newmessage.append(s+": ");
368
					newmessage.append(s+": ");
367
					newmessage.append(issues_titles.get(s));
369
					newmessage.append(issues_titles.get(s));
368
					newmessage.append("\n");
370
					newmessage.append("\n");
369
				}
371
				}
370
				postCommitUpdate(new File(svnadmin), repos, locale, encoding, rev, newmessage.toString());
372
				postCommitUpdate(new File(svnadmin), repos, locale, encoding, rev, newmessage.toString());
371
			}
373
			}
372
			
374
			
373
			/*
375
			/*
374
			 * XML processing phase
376
			 * XML processing phase
375
			 */			
377
			 */			
376
			if(isXmlProcessingEnabled) {
378
			if(isXmlProcessingEnabled) {
377
				
379
				
378
				
380
				
379
			}
381
			}
380
			
382
			
381
		
383
		
382
			/*
384
			/*
383
			 * ALF Event Send phase
385
			 * ALF Event Send phase
384
			 */
386
			 */
385
			String eventmanager = null;
387
			String eventmanager = null;
386
			if(isSoapEnabled) {
388
			if(isSoapEnabled) {
387
				eventmanager 		= 	readConfPropertyAsString(OPTION_EVENTMANAGER_URL, null, true, null);
389
				eventmanager 		= 	readConfPropertyAsString(OPTION_EVENTMANAGER_URL, null, true, null);
388
			}
390
			}
389
 
391
 
390
			
392
			
391
			
393
			
392
		
394
		
393
		/**
395
		/**
394
		 * Event XML Erzeugen
396
		 * Event XML Erzeugen
395
		 */
397
		 */
396
		try {
398
		try {
397
			String resultxml=null;
399
			String resultxml=null;
398
			if(isXmlProcessingEnabled) {
400
			if(isXmlProcessingEnabled) {
399
				
401
				
400
				processXml();
402
				processXml();
401
				addALFSecurity();
403
				addALFSecurity();
402
				addEventHeader();
404
				addEventHeader();
403
				
405
				
404
				// Serialize xml message to String
406
				// Serialize xml message to String
405
				StringWriter out = new StringWriter();
407
				StringWriter out = new StringWriter();
406
				template.getParent().serialize(out);
408
				template.getParent().serialize(out);
407
				out.flush();
409
				out.flush();
408
				
410
				
409
				resultxml =  out.getBuffer().toString();
411
				resultxml =  out.getBuffer().toString();
410
				if(isTrace) logger.debug("ALFEvent result:\n"+resultxml);
412
				if(isTrace) logger.debug("ALFEvent result:\n"+resultxml);
411
		
413
		
412
			} else {
414
			} else {
413
				logger.debug("Xml processing is deactivated.");
415
				logger.debug("Xml processing is deactivated.");
414
			}
416
			}
415
		
417
		
416
			if(isSoapEnabled && isXmlProcessingEnabled) {
418
			if(isSoapEnabled && isXmlProcessingEnabled) {
417
				final boolean isDropResponse 	= readConfPropertyAsBoolean(OPTION_IS_DROPENABLED, true, true, null);
419
				final boolean isDropResponse 	= readConfPropertyAsBoolean(OPTION_IS_DROPENABLED, true, true, null);
418
				SimpleHttpEvent sender = new SimpleHttpEvent(eventmanager, resultxml);
420
				SimpleHttpEvent sender = new SimpleHttpEvent(eventmanager, resultxml);
419
				sender.sendSoap(isDropResponse);
421
				sender.sendSoap(isDropResponse);
420
				logger.debug(String.format("Sending/ receiving the soap message took '%s' milliseconds.", sender.getDuration()));
422
				logger.debug(String.format("Sending/ receiving the soap message took '%s' milliseconds.", sender.getDuration()));
421
			} else {
423
			} else {
422
				logger.warn("Sending soap message and/ or xml processing is deactivated.");
424
				logger.warn("Sending soap message and/ or xml processing is deactivated.");
423
			}
425
			}
424
			
426
			
425
			
427
			
426
		} catch (FileNotFoundException e) {
428
		} catch (FileNotFoundException e) {
427
			logger.error(e.getMessage(), e);
429
			logger.error(e.getMessage(), e);
428
			this.exit(1);
430
			this.exit(1);
429
		} catch (ClientProtocolException e) {
431
		} catch (ClientProtocolException e) {
430
			logger.error(e.getMessage(), e);
432
			logger.error(e.getMessage(), e);
431
			this.exit(1);
433
			this.exit(1);
432
		} catch (IOException e) {
434
		} catch (IOException e) {
433
			logger.error(e.getMessage(), e);
435
			logger.error(e.getMessage(), e);
434
			this.exit(1);
436
			this.exit(1);
435
		} catch (XMLStreamException e) {
437
		} catch (XMLStreamException e) {
436
			logger.error(e.getMessage(), e);
438
			logger.error(e.getMessage(), e);
437
			this.exit(1);
439
			this.exit(1);
438
		} catch (JaxenException e) {
440
		} catch (JaxenException e) {
439
			logger.error(e.getMessage(), e);
441
			logger.error(e.getMessage(), e);
440
			this.exit(1);
442
			this.exit(1);
441
		} finally {
443
		} finally {
442
			String forcefail = config.getString(OPTION_IS_FORCEFAILENABLED, "");
444
			String forcefail = config.getString(OPTION_IS_FORCEFAILENABLED, "");
443
			if(forcefail.length()>0) {
445
			if(forcefail.length()>0) {
444
				logger.warn("Force fail is active. All commits will be blocked.");
446
				logger.warn("Force fail is active. All commits will be blocked.");
445
				this.exit(1);
447
				this.exit(1);
446
			}
448
			}
447
			
449
			
448
		}
450
		}
449
		
451
		
450
	}
452
	}
451
		private void addEventHeader() throws JaxenException {
453
		private void addEventHeader() throws JaxenException {
452
			AXIOMXPath path = new AXIOMXPath("//bru1:Base/bru1:EventId");
454
			AXIOMXPath path = new AXIOMXPath("//bru1:Base/bru1:EventId");
453
			path.addNamespace("bru1",  nss);
455
			path.addNamespace("bru1",  nss);
454
			OMElement n = (OMElement) path.selectSingleNode(template);
456
			OMElement n = (OMElement) path.selectSingleNode(template);
455
			if(n==null) {
457
			if(n==null) {
456
				logger.error("<Base> element in message is incomplete. <EventId> is missing.");
458
				logger.error("<Base> element in message is incomplete. <EventId> is missing.");
457
			} else {
459
			} else {
458
				n.addChild( n.getOMFactory().createOMText("1"));
460
				n.addChild( n.getOMFactory().createOMText("1"));
459
			}
461
			}
460
			
462
			
461
			path = new AXIOMXPath("//bru1:Base/bru1:ObjectId");
463
			path = new AXIOMXPath("//bru1:Base/bru1:ObjectId");
462
			path.addNamespace("bru1",  nss);
464
			path.addNamespace("bru1",  nss);
463
			n = (OMElement) path.selectSingleNode(template);
465
			n = (OMElement) path.selectSingleNode(template);
464
			if(n==null) {
466
			if(n==null) {
465
				logger.error("<Base> element in message is incomplete. <ObjectId> is missing.");
467
				logger.error("<Base> element in message is incomplete. <ObjectId> is missing.");
466
			} else {
468
			} else {
467
				n.addChild( n.getOMFactory().createOMText(info.getTxn() ));
469
				n.addChild( n.getOMFactory().createOMText(info.getTxn() ));
468
			}
470
			}
469
		}
471
		}
470
	
472
	
471
		private void addALFSecurity() throws ConfigurationException, JaxenException {
473
		private void addALFSecurity() throws ConfigurationException, JaxenException {
472
			final String eventmanager_user 	= 	readConfPropertyAsString(OPTION_EVENTMANAGER_USER, null, false, null);
474
			final String eventmanager_user 	= 	readConfPropertyAsString(OPTION_EVENTMANAGER_USER, null, false, null);
473
			final String eventmanager_pass 	= 	readConfPropertyAsString(OPTION_EVENTMANAGER_PASSWORD, null, false, null);
475
			String eventmanager_pass 	= 	readConfPropertyAsString(OPTION_EVENTMANAGER_PASSWORD, null, false, null);
-
 
476
			final boolean eventmanager_enc  =   readConfPropertyAsBoolean(OPTION_EVENTMANAGER_ENCRYPTED, false, false, null);
-
 
477
			if(eventmanager_enc) eventmanager_pass = PasswordEncrypter.decrypt(eventmanager_pass);
-
 
478
			
474
			AXIOMXPath path = new AXIOMXPath("//bru1:User");
479
			AXIOMXPath path = new AXIOMXPath("//bru1:User");
475
			OMNamespace ns = template.findNamespace(nss, null);
480
			OMNamespace ns = template.findNamespace(nss, null);
476
			path.addNamespace("bru1", nss);
481
			path.addNamespace("bru1", nss);
477
			OMElement n = (OMElement) path.selectSingleNode(template);
482
			OMElement n = (OMElement) path.selectSingleNode(template);
478
			if(n== null) { 
483
			if(n== null) { 
479
				logger.warn( String.format("<User> element was not found in namespace '%s'. Cannot add ALFSecurity elements. This is required since SBM 10.1.x.", nss));
484
				logger.warn( String.format("<User> element was not found in namespace '%s'. Cannot add ALFSecurity elements. This is required since SBM 10.1.x.", nss));
480
			} else {
485
			} else {
481
				/*
486
				/*
482
				 *  <ns:User>
487
				 *  <ns:User>
483
            		<!--Optional:-->
488
            		<!--Optional:-->
484
               		<ns:ALFSecurity>
489
               		<ns:ALFSecurity>
485
                  		<ns:UsernameToken>
490
                  		<ns:UsernameToken>
486
                     		<ns:Username>admin</ns:Username>
491
                     		<ns:Username>admin</ns:Username>
487
                     		<ns:Password></ns:Password>
492
                     		<ns:Password></ns:Password>
488
                  		</ns:UsernameToken>
493
                  		</ns:UsernameToken>
489
               		</ns:ALFSecurity>
494
               		</ns:ALFSecurity>
490
					</ns:User> 
495
					</ns:User> 
491
				 */
496
				 */
492
				n.removeChildren();
497
				n.removeChildren();
493
				OMFactory fac = n.getOMFactory();
498
				OMFactory fac = n.getOMFactory();
494
				fac.createOMComment(n, "Generated by SVN-ALFEmitter");
499
				fac.createOMComment(n, "Generated by SVN-ALFEmitter");
495
				OMElement sec = fac.createOMElement("ALFSecurity", ns);
500
				OMElement sec = fac.createOMElement("ALFSecurity", ns);
496
				OMElement token = fac.createOMElement("UsernameToken", ns);
501
				OMElement token = fac.createOMElement("UsernameToken", ns);
497
				OMElement user = fac.createOMElement("Username", ns);
502
				OMElement user = fac.createOMElement("Username", ns);
498
				user.addChild( fac.createOMText(eventmanager_user));
503
				user.addChild( fac.createOMText(eventmanager_user));
499
				OMElement pass = fac.createOMElement("Password", ns);
504
				OMElement pass = fac.createOMElement("Password", ns);
500
				pass.addChild(fac.createOMText(eventmanager_pass, OMNode.CDATA_SECTION_NODE));
505
				pass.addChild(fac.createOMText(eventmanager_pass, OMNode.CDATA_SECTION_NODE));
501
				token.addChild( user );
506
				token.addChild( user );
502
				token.addChild( pass);
507
				token.addChild( pass);
503
				sec.addChild(token);
508
				sec.addChild(token);
504
				n.addChild(sec);				
509
				n.addChild(sec);				
505
			}
510
			}
506
		}
511
		}
507
	
512
	
508
		private void processXml() throws ConfigurationException, JaxenException {
513
		private void processXml() throws ConfigurationException, JaxenException {
509
			// read additional configuration
514
			// read additional configuration
510
			final String eventtemplate 		= 	readConfPropertyAsString(OPTION_EVENTTEMPLATE, null, true, null);
515
			final String eventtemplate 		= 	readConfPropertyAsString(OPTION_EVENTTEMPLATE, null, true, null);
511
			EmitterUtil.verifyFile(eventtemplate, false, false);
516
			EmitterUtil.verifyFile(eventtemplate, false, false);
512
			try {
517
			try {
513
				template = OMXMLBuilderFactory.createOMBuilder(new FileInputStream(new File(eventtemplate)))
518
				template = OMXMLBuilderFactory.createOMBuilder(new FileInputStream(new File(eventtemplate)))
514
						.getDocument().getOMDocumentElement();
519
						.getDocument().getOMDocumentElement();
515
			} catch (FileNotFoundException e1) {
520
			} catch (FileNotFoundException e1) {
516
				logger.error(String.format("Could not load XML event template from file '%s'.", eventtemplate), e1);
521
				logger.error(String.format("Could not load XML event template from file '%s'.", eventtemplate), e1);
517
				this.exit(1);
522
				this.exit(1);
518
			}
523
			}
519
			nss 	= 	readConfPropertyAsString(OPTION_EVENTNAMESPACE, "http://www.eclipse.org/alf/schema/EventBase/1", true, null);
524
			nss 	= 	readConfPropertyAsString(OPTION_EVENTNAMESPACE, "http://www.eclipse.org/alf/schema/EventBase/1", true, null);
520
			final String marker_logmessage 	= 	readConfPropertyAsString(OPTION_MARKER_LOGMESSAGE, "@@logmessage@@", true, null);
525
			final String marker_logmessage 	= 	readConfPropertyAsString(OPTION_MARKER_LOGMESSAGE, "@@logmessage@@", true, null);
521
			final String marker_author 		= 	readConfPropertyAsString(OPTION_MARKER_AUTHOR, "@@author@@", true, null);
526
			final String marker_author 		= 	readConfPropertyAsString(OPTION_MARKER_AUTHOR, "@@author@@", true, null);
522
			final String marker_revision	= 	readConfPropertyAsString(OPTION_MARKER_REVISION, "@@revision@@", true, null);
527
			final String marker_revision	= 	readConfPropertyAsString(OPTION_MARKER_REVISION, "@@revision@@", true, null);
523
			final String marker_addedfiles 	= 	readConfPropertyAsString(OPTION_MARKER_ADDEDFILES, "@@addedfiles@@", true, null);
528
			final String marker_addedfiles 	= 	readConfPropertyAsString(OPTION_MARKER_ADDEDFILES, "@@addedfiles@@", true, null);
524
			final String marker_deletedfiles = 	readConfPropertyAsString(OPTION_MARKER_DELETEDFILES, "@@deletedfiles@@", true, null);
529
			final String marker_deletedfiles = 	readConfPropertyAsString(OPTION_MARKER_DELETEDFILES, "@@deletedfiles@@", true, null);
525
			final String marker_changedfiles = 	readConfPropertyAsString(OPTION_MARKER_CHANGEDFILES, "@@changedfiles@@", true, null);
530
			final String marker_changedfiles = 	readConfPropertyAsString(OPTION_MARKER_CHANGEDFILES, "@@changedfiles@@", true, null);
526
			final String marker_fileselementname = readConfPropertyAsString("marker.fileselementname", "file", true, null);
531
			final String marker_fileselementname = readConfPropertyAsString("marker.fileselementname", "file", true, null);
527
			final String marker_issues 		= 	readConfPropertyAsString(OPTION_MARKER_ISSUES, "@@issues@@", true, null);
532
			final String marker_issues 		= 	readConfPropertyAsString(OPTION_MARKER_ISSUES, "@@issues@@", true, null);
528
			final String marker_issueselementname = readConfPropertyAsString("marker.issueselementname", "issue", true, null);
533
			final String marker_issueselementname = readConfPropertyAsString("marker.issueselementname", "issue", true, null);
529
			final String marker_internalissues    = readConfPropertyAsString(OPTION_MARKER_INTERNALISSUES, "@@internalissues@@", true, null);
534
			final String marker_internalissues    = readConfPropertyAsString(OPTION_MARKER_INTERNALISSUES, "@@internalissues@@", true, null);
530
	
535
	
531
			SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
536
			SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
532
			String datestring = f.format(info.getDate());
537
			String datestring = f.format(info.getDate());
533
			datestring= datestring.substring(0, 26) + ":" + datestring.substring(26); //hack into ISO 8601 format
538
			datestring= datestring.substring(0, 26) + ":" + datestring.substring(26); //hack into ISO 8601 format
534
			
539
			
535
			// add content from SVNCommitInfo object where
540
			// add content from SVNCommitInfo object where
536
			// XML commit markers are
541
			// XML commit markers are
537
			addElement( marker_logmessage, info.getLogmessage(), true);
542
			addElement( marker_logmessage, info.getLogmessage(), true);
538
			addElement(marker_author, info.getAuthor(), false);
543
			addElement(marker_author, info.getAuthor(), false);
539
			addElement(marker_revision, info.getRev(), false);
544
			addElement(marker_revision, info.getRev(), false);
540
			addElement("@@timestamp@@", datestring, false);
545
			addElement("@@timestamp@@", datestring, false);
541
			addElements(marker_changedfiles, info.getChangedFiles(), marker_fileselementname);
546
			addElements(marker_changedfiles, info.getChangedFiles(), marker_fileselementname);
542
			addElements(marker_deletedfiles, info.getDeletedFiles(), marker_fileselementname);
547
			addElements(marker_deletedfiles, info.getDeletedFiles(), marker_fileselementname);
543
			addElements(marker_addedfiles, info.getAddedFiles(), marker_fileselementname);
548
			addElements(marker_addedfiles, info.getAddedFiles(), marker_fileselementname);
544
			addElements(marker_issues, info.getIssues(), marker_issueselementname);
549
			addElements(marker_issues, info.getIssues(), marker_issueselementname);
545
			addElements(marker_internalissues, internalissues, marker_issueselementname);
550
			addElements(marker_internalissues, internalissues, marker_issueselementname);
546
			
551
			
547
		}
552
		}
548
	
553
	
549
		private boolean verify(List<String> issues, boolean isTrace) throws MalformedURLException {
554
		private boolean verify(List<String> issues, boolean isTrace) throws MalformedURLException {
550
		
555
		
551
			for(String issueid : issues) {
556
			for(String issueid : issues) {
552
				TTItemList items = getTTItems(issueid, isTrace);
557
				TTItemList items = getTTItems(issueid, isTrace);
553
				if(items == null) {
558
				if(items == null) {
554
					return false;
559
					return false;
555
				}
560
				}
556
			}
561
			}
557
			return true;			
562
			return true;			
558
	}
563
	}
559
		
564
		
560
		
565
		
561
		private TTItemList getTTItems(String issueid, boolean isTrace) throws MalformedURLException {
566
		private TTItemList getTTItems(String issueid, boolean isTrace) throws MalformedURLException {
562
			long startTime = System.currentTimeMillis();
567
			long startTime = System.currentTimeMillis();
563
			Sbmappservices72PortType port = null;
568
			Sbmappservices72PortType port = null;
564
			//try {
-
 
565
			//	JCS cache = JCS.getInstance("FileCache");
-
 
566
 
-
 
567
				/* -- */
-
 
568
			//	port = (Sbmappservices72PortType)cache.get(CACHE_SBMPORT);
-
 
569
			/*
-
 
570
				if(port==null) {
-
 
571
					Sbmappservices72 ss = new Sbmappservices72(ClassLoader.getSystemResource("sbmappservices72.wsdl") );
-
 
572
					
-
 
573
					port = ss.getSbmappservices72();
-
 
574
 
-
 
575
					
-
 
576
					BindingProvider bindingProvider = (BindingProvider) port;
-
 
577
			        bindingProvider.getRequestContext().put(
-
 
578
			        BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
-
 
579
				}
-
 
580
				*/
-
 
581
		    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
569
		    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
582
		    factory.setServiceClass(Sbmappservices72PortType.class);
570
		    factory.setServiceClass(Sbmappservices72PortType.class);
583
		    factory.setAddress(endpoint);
571
		    factory.setAddress(endpoint);
584
		    port = (Sbmappservices72PortType) factory.create();
572
		    port = (Sbmappservices72PortType) factory.create();
585
		    logger.debug("Total execution of sbmappservices72 wsdl read took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
573
		    logger.debug("Total execution of sbmappservices72 wsdl read took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
586
		 
574
		 
587
			        
-
 
588
			//		cache.put(CACHE_SBMPORT, port);
-
 
589
			//		cache.dispose();
-
 
590
			//	} else {
-
 
591
			//		logger.debug("sbmappservices72 port was read from cache.");
-
 
592
			//	}
-
 
593
				
-
 
594
			//} catch (CacheException e1) {
-
 
595
			//	// TODO Auto-generated catch block
-
 
596
			//	e1.printStackTrace();
-
 
597
			//	this.exit(1);
-
 
598
			//}
-
 
599
			
575
			        	
600
			if(isTrace) {
576
			if(isTrace) {
601
				Client client = ClientProxy.getClient(port);
577
				Client client = ClientProxy.getClient(port);
602
		        client.getInInterceptors().add(new LoggingInInterceptor());
578
		        client.getInInterceptors().add(new LoggingInInterceptor());
603
		        client.getOutInterceptors().add(new LoggingOutInterceptor());
579
		        client.getOutInterceptors().add(new LoggingOutInterceptor());
604
			}
580
			}
605
 
581
 
606
	        /* -- */
582
	        /* -- */
607
	        logger.debug("Total execution of sbmappservices72 initialisation took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
583
	        logger.debug("Total execution of sbmappservices72 initialisation took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
608
	        
584
	        
609
			ObjectFactory fac = new ObjectFactory();
585
			ObjectFactory fac = new ObjectFactory();
610
			Auth auth = fac.createAuth();
586
			Auth auth = fac.createAuth();
611
			auth.setUserId(fac.createAuthUserId(sbm_user));
587
			auth.setUserId(fac.createAuthUserId(sbm_user));
612
			auth.setPassword(fac.createAuthPassword(sbm_pass));
588
			auth.setPassword(fac.createAuthPassword(sbm_pass));
613
			
589
			
614
			TableIdentifier table = fac.createTableIdentifier();
590
			TableIdentifier table = fac.createTableIdentifier();
615
			table.setDbName(fac.createTableIdentifierDbName(querytable));
591
			table.setDbName(fac.createTableIdentifierDbName(querytable));
616
			
592
			
617
			MultipleResponseItemOptions options = fac.createMultipleResponseItemOptions();
593
			MultipleResponseItemOptions options = fac.createMultipleResponseItemOptions();
618
			options.setSpecifiedSections(fac.createResponseItemOptionsSpecifiedSections("SECTION:FIXED"));
594
			options.setSpecifiedSections(fac.createResponseItemOptionsSpecifiedSections("SECTION:FIXED"));
619
			options.setSections(SectionsOption.SECTIONS_SPECIFIED);
595
			options.setSections(SectionsOption.SECTIONS_SPECIFIED);
620
			
596
			
621
			issueid = issueid.replaceAll("[^0-9]", "");
597
			issueid = issueid.replaceAll("[^0-9]", "");
622
			String queryWhereClause = "TS_ISSUEID = '"+issueid+"'";
598
			String queryWhereClause = "TS_ISSUEID = '"+issueid+"'";
623
			if(query!=null && query.length()>0) queryWhereClause = queryWhereClause + " And " + query;
599
			if(query!=null && query.length()>0) queryWhereClause = queryWhereClause + " And " + query;
624
			TTItemList items = null;
600
			TTItemList items = null;
625
			logger.debug(String.format("Using query against table '%s'. Query where clause: '%s'", querytable, queryWhereClause ));
601
			logger.debug(String.format("Using query against table '%s'. Query where clause: '%s'", querytable, queryWhereClause ));
626
			try {
602
			try {
627
					startTime = System.currentTimeMillis();
603
					startTime = System.currentTimeMillis();
628
					items = port.getItemsByQuery(auth, table, queryWhereClause, "", null, BigInteger.valueOf(1), options);
604
					items = port.getItemsByQuery(auth, table, queryWhereClause, "", null, BigInteger.valueOf(1), options);
629
					logger.debug("Total execution of sbmappservices72 GetItems took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
605
					logger.debug("Total execution of sbmappservices72 GetItems took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
630
					
606
					
631
					//Marshaller m = JAXBContext.newInstance(TTItemList.class).createMarshaller();
607
					//Marshaller m = JAXBContext.newInstance(TTItemList.class).createMarshaller();
632
					//m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
608
					//m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
633
					//m.marshal( new JAXBElement<TTItemList>(new QName("uri","local"), TTItemList.class, items), System.err);
609
					//m.marshal( new JAXBElement<TTItemList>(new QName("uri","local"), TTItemList.class, items), System.err);
634
					
610
					
635
					logger.debug(String.format("Got Response from getItemsByQuery"));
611
					logger.debug(String.format("Got Response from getItemsByQuery"));
636
					if(items!=null) {
612
					if(items!=null) {
637
						logger.debug(String.format("Verification query matched '%s' item(s) for issue '%s.'",items.getTotalCount(), issueid));
613
						logger.debug(String.format("Verification query matched '%s' item(s) for issue '%s.'",items.getTotalCount(), issueid));
638
					}
614
					}
639
					if(items.getTotalCount().intValue()<=0) {
615
					if(items.getTotalCount().intValue()<=0) {
640
						return null;
616
						return null;
641
					} else {
617
					} else {
642
						/* store internal ids (tableid:itemid) */
618
						/* store internal ids (tableid:itemid) */
643
						internalissues.add(items.getItem().get(0).getId().getValue().getTableIdItemId().getValue());
619
						internalissues.add(items.getItem().get(0).getId().getValue().getTableIdItemId().getValue());
644
						/* Store a map entry with internal id and title */
620
						/* Store a map entry with internal id and title */
645
						issues_titles.put(items.getItem().get(0).getId().getValue().getDisplayName().getValue(), 
621
						issues_titles.put(items.getItem().get(0).getId().getValue().getDisplayName().getValue(), 
646
											items.getItem().get(0).getTitle().getValue());
622
											items.getItem().get(0).getTitle().getValue());
647
						
623
						
648
					}
624
					}
649
					
625
					
650
			} catch (AEWebservicesFaultFault e) {
626
			} catch (AEWebservicesFaultFault e) {
651
					logger.debug("Web service fault: " + e.getFaultInfo());
627
					logger.debug("Web service fault: " + e.getFaultInfo());
652
			} catch (Exception e) {
628
			} catch (Exception e) {
653
					logger.debug("Unknown Exception", e);
629
					logger.debug("Unknown Exception", e);
654
			}
630
			}
655
			return items;	
631
			return items;	
656
		}
632
		}
657
		
633
		
658
		private void postCommitUpdate(File svnadmin, String repos, String locale, String encoding, String revision, String newmessage) {
634
		private void postCommitUpdate(File svnadmin, String repos, String locale, String encoding, String revision, String newmessage) {
659
			SVNAdminExecutor exec = new SVNAdminExecutor(svnadmin, repos);
635
			SVNAdminExecutor exec = new SVNAdminExecutor(svnadmin, repos);
660
			exec.setRev(revision);
636
			exec.setRev(revision);
661
			exec.setMessage(newmessage);
637
			exec.setMessage(newmessage);
662
			exec.setEncoding(encoding);
638
			exec.setEncoding(encoding);
663
			exec.setLocale(locale);
639
			exec.setLocale(locale);
664
			exec.executeSVNAdmin(SVNAdminCommand.SETLOG);			
640
			exec.executeSVNAdmin(SVNAdminCommand.SETLOG);			
665
		}
641
		}
666
 
642
 
667
		private void addElement(String pattern, String newCdata, boolean wrapCDATA) throws JaxenException {
643
		private void addElement(String pattern, String newCdata, boolean wrapCDATA) throws JaxenException {
668
			OMComment comment = findComment(pattern);
644
			OMComment comment = findComment(pattern);
669
			if(comment!=null) {
645
			if(comment!=null) {
670
				OMFactory fac = OMAbstractFactory.getOMFactory();
646
				OMFactory fac = OMAbstractFactory.getOMFactory();
671
				int type = OMNode.TEXT_NODE;
647
				int type = OMNode.TEXT_NODE;
672
				if(wrapCDATA) {
648
				if(wrapCDATA) {
673
					type = OMNode.CDATA_SECTION_NODE;
649
					type = OMNode.CDATA_SECTION_NODE;
674
				}
650
				}
675
				OMText text = fac.createOMText(newCdata, type);
651
				OMText text = fac.createOMText(newCdata, type);
676
				comment.insertSiblingAfter(text);
652
				comment.insertSiblingAfter(text);
677
			}			
653
			}			
678
		}
654
		}
679
		
655
		
680
		private void addElements(String pattern, List<String> files, String elementName) throws JaxenException {
656
		private void addElements(String pattern, List<String> files, String elementName) throws JaxenException {
681
			if(files.size()<=0) return;
657
			if(files.size()<=0) return;
682
			OMComment comment = findComment(pattern);
658
			OMComment comment = findComment(pattern);
683
			if(comment!=null) {
659
			if(comment!=null) {
684
				OMFactory fac = OMAbstractFactory.getOMFactory();
660
				OMFactory fac = OMAbstractFactory.getOMFactory();
685
				OMNamespace ns = template.findNamespace(nss, null);
661
				OMNamespace ns = template.findNamespace(nss, null);
686
				if(ns == null) logger.error(String.format("The namespace '%s' is not defined in the template.", nss));
662
				if(ns == null) logger.error(String.format("The namespace '%s' is not defined in the template.", nss));
687
				for(String s : files) {
663
				for(String s : files) {
688
					OMElement e = fac.createOMElement(elementName, ns);
664
					OMElement e = fac.createOMElement(elementName, ns);
689
					OMText text = fac.createOMText(s, OMNode.TEXT_NODE);
665
					OMText text = fac.createOMText(s, OMNode.TEXT_NODE);
690
					e.addChild(text);
666
					e.addChild(text);
691
					comment.insertSiblingAfter(e);
667
					comment.insertSiblingAfter(e);
692
				}				
668
				}				
693
			}
669
			}
694
		}
670
		}
695
		
671
		
696
	
672
	
697
		private OMComment findComment(String pattern) throws JaxenException {
673
		private OMComment findComment(String pattern) throws JaxenException {
698
			AXIOMXPath path = new AXIOMXPath("//comment()[. = '"+pattern+"'][1]");
674
			AXIOMXPath path = new AXIOMXPath("//comment()[. = '"+pattern+"'][1]");
699
			//OMNamespace ns = template.findNamespace(nss, null);
675
			//OMNamespace ns = template.findNamespace(nss, null);
700
			path.addNamespace("bru1", nss);
676
			path.addNamespace("bru1", nss);
701
			OMComment n = (OMComment) path.selectSingleNode(template);
677
			OMComment n = (OMComment) path.selectSingleNode(template);
702
			if(n!=null) return n;
678
			if(n!=null) return n;
703
			logger.warn("Comment '"+pattern+"' was not found in the XML template.");
679
			logger.warn("Comment '"+pattern+"' was not found in the XML template.");
704
			return null;
680
			return null;
705
		}
681
		}
706
		
682
		
707
	private void exit(int errorCode) {
683
	private void exit(int errorCode) {
708
		long endTime = System.currentTimeMillis();
684
		long endTime = System.currentTimeMillis();
709
		logger.debug("Total execution took '"+(endTime-startTime)+"' milliseconds.");
685
		logger.debug("Total execution took '"+(endTime-startTime)+"' milliseconds.");
710
		System.exit(errorCode);
686
		System.exit(errorCode);
711
	}
687
	}
712
	
688
	
713
	@SuppressWarnings("static-access")
689
	@SuppressWarnings("static-access")
714
	private static Options getOptions() {
690
	private static Options getOptions() {
715
		Option repository = OptionBuilder.withArgName( "repository" )
691
		Option repository = OptionBuilder.withArgName( "repository" )
716
											.hasArg()
692
											.hasArg()
717
											.withLongOpt("repository")
693
											.withLongOpt("repository")
718
											.withDescription(  "Path or URL to the SVN repository." )
694
											.withDescription(  "Path or URL to the SVN repository." )
719
											.create( PARAM_REPOS );
695
											.create( PARAM_REPOS );
720
		repository.setRequired(true);
696
		repository.setRequired(true);
721
		
697
		
722
		Option txn = OptionBuilder.withArgName( "transactionid" )
698
		Option txn = OptionBuilder.withArgName( "transactionid" )
723
											.hasArg()
699
											.hasArg()
724
											.withLongOpt("transaction")
700
											.withLongOpt("transaction")
725
											.withDescription(  "The SVN transaction id to examine (TXN). You cannot combine txn with -rev. "
701
											.withDescription(  "The SVN transaction id to examine (TXN). You cannot combine txn with -rev. "
726
													+ "When a txn is given, the repository path must be a local path.")
702
													+ "When a txn is given, the repository path must be a local path.")
727
											.create( PARAM_TXN );
703
											.create( PARAM_TXN );
728
		Option rev = OptionBuilder.withArgName( "revision" )
704
		Option rev = OptionBuilder.withArgName( "revision" )
729
				.hasArg()
705
				.hasArg()
730
				.withDescription(  "A revision to examine. You cannot combine revision with -txn." )
706
				.withDescription(  "A revision to examine. You cannot combine revision with -txn." )
731
				.create( PARAM_REV );
707
				.create( PARAM_REV );
732
		Option config = OptionBuilder.withArgName( "config_file" )
708
		Option config = OptionBuilder.withArgName( "config_file" )
733
				.hasArg()
709
				.hasArg()
734
				.withLongOpt("config")
710
				.withLongOpt("config")
735
				.withDescription(  "The configuration file to use. Defaults to 'emitter.properties'.")
711
				.withDescription(  "The configuration file to use. Defaults to 'emitter.properties'.")
736
				.create( PARAM_CONFIG );
712
				.create( PARAM_CONFIG );
737
		
713
		
738
		Options options = new Options();
714
		Options options = new Options();
739
		options.addOption(repository);
715
		options.addOption(repository);
740
		options.addOption(txn);
716
		options.addOption(txn);
741
		options.addOption(rev);
717
		options.addOption(rev);
742
		options.addOption(config);
718
		options.addOption(config);
743
		return options;
719
		return options;
744
	}
720
	}
745
	
721
	
746
	private static void printHelp() {
722
	private static void printHelp() {
747
		// automatically generate the help statement
723
		// automatically generate the help statement
748
		HelpFormatter formatter = new HelpFormatter();
724
		HelpFormatter formatter = new HelpFormatter();
749
		String header = "\nSVN-ALFEventEmitter " + VERSION +", a SVN hook implemented in Java to emit Eclipse ALFEvents on commit.\n\n";
725
		String header = "\nSVN-ALFEventEmitter " + VERSION +", a SVN hook implemented in Java to emit Eclipse ALFEvents on commit.\n\n";
750
		String footer = "Please send bug reports to bru@brutex.de.\n(c)2014 Brian Rosenberger";
726
		String footer = "Please send bug reports to bru@brutex.de.\n(c)2014 Brian Rosenberger";
751
		formatter.printHelp("java -jar SVN-ALFEventEmitter", header, getOptions(), footer, true);
727
		formatter.printHelp("java -jar SVN-ALFEventEmitter", header, getOptions(), footer, true);
752
	}
728
	}
753
	
729
	
754
	
730
	
755
	
731
	
756
	private enum PropertyType {
732
	private enum PropertyType {
757
		STRING(), STRINGARRAY(), BOOLEAN();
733
		STRING(), STRINGARRAY(), BOOLEAN();
758
	}
734
	}
759
	
735
	
760
	
736
	
761
}
737
}