Subversion Repositories XServices

Rev

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

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