Subversion Repositories XServices

Rev

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

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