Subversion Repositories XServices

Rev

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

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