Subversion Repositories XServices

Compare Revisions

No changes between revisions

Ignore whitespace Rev 166 → Rev 167

/SVN-ALFEventEmitter/trunk/src/net/brutex/svn/SVNAdminCommand.java
0,0 → 1,40
/*
* Copyright 2014 Brian Rosenberger (Brutex Network)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.brutex.svn;
 
/**
* The Enum SVNAdminCommand. Lists supported svnladmin commands
*
* @author Brian Rosenberger, bru(at)brutex.de
* @since 0.1
*/
public enum SVNAdminCommand {
 
SETLOG("setlog");
private final String value;
private SVNAdminCommand(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
 
}
Property changes:
Added: svn:mime-type
+text/plain
\ No newline at end of property
/SVN-ALFEventEmitter/trunk/src/net/brutex/svn/SVNAdminExecutor.java
0,0 → 1,181
/*
* Copyright 2014 Brian Rosenberger (Brutex Network)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.brutex.svn;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
 
import org.apache.log4j.Logger;
 
/* Executes the svnadmin utility
*
* @author Brian Rosenberger bru(at)brutex.de
* @since 0.1
 
*/
public class SVNAdminExecutor {
private Logger logger = Logger.getLogger(SVNAdminExecutor.class);
private final File svnadmin;
private final String repos;
private String rev = null;
private String message = null;
private String locale = "de_DE.UTF-8";
private String encoding = "UTF-8";
private boolean useBypassHooks = true;
/**
* Instantiates a new SVN admin executor.
*
* @param svnadmin the svnadmin
* @param repos the repos
*/
public SVNAdminExecutor(File svnadmin, String repos) {
if(! svnadmin.exists() ) throw new IllegalArgumentException( String.format("The svnadmin executable at '%s' does not exist.", svnadmin.toString()));
if(! svnadmin.isFile() ) throw new IllegalArgumentException( String.format("The svnadmin utility at'%s' is not a file.", svnadmin.toString()));
logger.debug(String.format("Instantiating '%s' with svnadmin at '%s'.", this.getClass().getCanonicalName(), svnadmin.toString()));
this.svnadmin = svnadmin;
logger.debug(String.format("Working against svn repository at '%s'.", repos));
this.repos = repos;
}
 
/**
* Execute svn admin.
*
* @param command the command
* @return the string
*/
public String executeSVNAdmin(SVNAdminCommand command) {
StringBuilder sb = new StringBuilder();
StringBuilder sberr = new StringBuilder();
if(rev==null) {
logger.error("The revision can not be 'null' for the svnadmin command.");
return null;
}
if(message==null) {
logger.error("The new log message can not be 'null' for the svnadmin command.");
return null;
}
File logfile = null;
try {
logfile = File.createTempFile("~msg"+rev+"_", ".tmp");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logfile), encoding));
out.write(message);
out.flush();
out.close();
} catch (IOException e) {
logger.error("Failed to write new log message to temporary file '"+logfile.getAbsolutePath()+"'.", e);
return null;
}
 
try {
List<String> cmdline = new ArrayList<String>(5);
cmdline.add(svnadmin.toString());
cmdline.add(command.getValue());
cmdline.add(repos);
if(useBypassHooks) {
cmdline.add("--bypass-hooks");
}
cmdline.add("-r");
cmdline.add(rev);
cmdline.add(logfile.getAbsolutePath());
 
ProcessBuilder pf = new ProcessBuilder(cmdline);
logger.debug(String.format("Executing svnadmin with commandline '%s'.", pf.command()));
Map<String, String> env = pf.environment();
env.put("LANG", locale);
Process svnprocess = pf.start();
BufferedReader stdin = new BufferedReader(new InputStreamReader(svnprocess.getInputStream(), encoding));
BufferedReader stderr = new BufferedReader(new InputStreamReader(svnprocess.getErrorStream(), encoding));
String s;
while( (s = stdin.readLine()) != null ) {
sb.append(s + '\n');
}
while( (s = stderr.readLine()) != null ) {
sberr.append(s + '\n');
}
stdin.close(); stderr.close();
} catch (IOException e) {
logger.error( String.format( "Error calling the svnadmin utility: '%s'", e.getMessage()));
e.printStackTrace();
} finally {
logfile.deleteOnExit();
}
String error = sberr.toString();
if( error.length()>0 ) {
error = "Failed to call svnadmin. The STDERR was '"+error+"'";
logger.error(error);
throw new IllegalArgumentException(error);
}
String output = sb.toString().trim();
logger.debug(String.format("Svnadmin output was '%s'", output));
return output;
}
public void setRev(String rev) {
if(rev==null || rev.length()<=0) throw new IllegalArgumentException("Revision cannot be null or empty.");
this.rev = rev;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Set the locale that will be pushed into
* 'LANG' environment variable.
*
* @param locale i.e. de_DE.UTF-8
*/
public void setLocale(String locale) {
this.locale = locale;
}
/**
* Set the new log message.
*
* @param message new message
*/
public void setMessage(String message) {
this.message = message;
}
/**
* Set this to true to bypass the pre-revprop-change and post-revprop-change
* hooks.
*
* @param useBypassHooks defaults to true
*/
public void setUseBypassHooks(boolean useBypassHooks) {
this.useBypassHooks = useBypassHooks;
}
 
}
Property changes:
Added: svn:mime-type
+text/plain
\ No newline at end of property
/SVN-ALFEventEmitter/trunk/src/net/brutex/emitter/ALFEmitter.java
21,10 → 21,14
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
 
import javax.xml.bind.JAXBContext;
56,6 → 60,8
import net.brutex.sbm.sbmappservices72.api.SectionsOption;
import net.brutex.sbm.sbmappservices72.api.TTItemList;
import net.brutex.sbm.sbmappservices72.api.TableIdentifier;
import net.brutex.svn.SVNAdminCommand;
import net.brutex.svn.SVNAdminExecutor;
import net.brutex.svn.SVNCommitInfo;
import net.brutex.svn.SVNLookExecutor;
 
88,7 → 94,9
import org.apache.log4j.Logger;
import org.jaxen.JaxenException;
 
import com.sun.xml.bind.v2.runtime.JAXBContextImpl;
 
 
/**
* The Class ALFEmitter.
*
104,6 → 112,7
// Keys to read from the configuration file.
//
private static final String OPTION_SVNLOOK = "svnlook";
private static final String OPTION_SVNADMIN = "svnadmin";
private static final String OPTION_LOCALE = "env.LANG";
private static final String OPTION_ENCODING = "env.encoding";
private static final String OPTION_ISSUEPATTERN = "issuepattern";
134,6 → 143,7
private static final String OPTION_IS_DROPENABLED = "isDropResponse";
private static final String OPTION_IS_FORCEFAILENABLED = "forcefail";
private static final String OPTION_IS_VERIFICATIONENABLED = "isWithVerification";
private static final String OPTION_IS_UPDATECOMMITMESSAGE = "isWithMessageUpdate";
private static final String OPTION_IS_WSTRACE = "trace";
private static final String OPTION_IS_XMLPROCESSINGENABLED = "isXmlProcessingEnabled";
 
166,6 → 176,8
 
private final List<String> internalissues = new ArrayList<String>();
//SBM IssueTypePrefix+IssueId, Title
private final Map<String, String> issues_titles = new HashMap<String, String>();
/**
* The main method.
187,6 → 199,9
ALFEmitter emitter = new ALFEmitter(cmd, startTime);
} catch (ConfigurationException e) {
System.exit(1);
} catch (MalformedURLException e) {
logger.error("Could not find/ load wsdl url.", e);
System.exit(1);
}
long endTime = System.currentTimeMillis();
logger.debug("Total execution took '"+(endTime-startTime)+"' milliseconds.");
262,7 → 277,7
return b.booleanValue();
}
private ALFEmitter(CommandLine cmd, long startTime) throws ConfigurationException {
private ALFEmitter(CommandLine cmd, long startTime) throws ConfigurationException, MalformedURLException {
this.startTime = startTime;
repos = cmd.getOptionValue(PARAM_REPOS);
txn = cmd.getOptionValue(PARAM_TXN);
277,7 → 292,7
config = new PropertiesConfiguration(config_file);
} catch (ConfigurationException e) {
logger.error("Could not find/ load '"+config_file+"' file.", e);
System.exit(1);
this.exit(1);
}
/*
300,6 → 315,7
final boolean isXmlProcessingEnabled = readConfPropertyAsBoolean(OPTION_IS_XMLPROCESSINGENABLED, true, true, null);
final boolean isWithVerification= readConfPropertyAsBoolean(OPTION_IS_VERIFICATIONENABLED, false, true, null);
final boolean isRemoveIssues = readConfPropertyAsBoolean(OPTION_REMOVE_ISSUES_FROM_COMMIT, false, true, "");
final boolean isWithCommitUpdate= readConfPropertyAsBoolean(OPTION_IS_UPDATECOMMITMESSAGE, false, true, "");
/*
* SVNLook phase
338,7 → 354,7
boolean isOK = verify(info.getIssues(), isTrace);
if(! isOK ) {
logger.error("Verification of issue failed. No matching issue was found.");
System.exit(1);
this.exit(1);
}
} else {
sbm_user = null; sbm_pass=null; endpoint=null; querytable=null; query=null;
345,6 → 361,31
}
 
/*
* Modify original commit message
* using svnadmin command
*/
if(isWithCommitUpdate) {
String svnadmin = readConfPropertyAsString(OPTION_SVNADMIN, null, true, null);
EmitterUtil.verifyFile(svnadmin, false, true);
/* If verification was turned on, we do already have the titles
* so only try to load the items when verification was off
*/
if(! isWithVerification) {
verify(info.getIssues(), isTrace);
}
/* Append associated items information and change log message */
StringBuffer newmessage = new StringBuffer();
newmessage.append(info.getLogmessage());
newmessage.append("\n\n Associated SBM items:\n");
for(String s : issues_titles.keySet()) {
newmessage.append(s+": ");
newmessage.append(issues_titles.get(s));
newmessage.append("\n");
}
postCommitUpdate(new File(svnadmin), repos, locale, encoding, rev, newmessage.toString());
}
/*
* XML processing phase
*/
if(isXmlProcessingEnabled) {
352,8 → 393,7
}
/*
* ALF Event Send phase
*/
400,25 → 440,24
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e);
System.exit(1);
this.exit(1);
} catch (ClientProtocolException e) {
logger.error(e.getMessage(), e);
System.exit(1);
this.exit(1);
} catch (IOException e) {
logger.error(e.getMessage(), e);
System.exit(1);
this.exit(1);
} catch (XMLStreamException e) {
logger.error(e.getMessage(), e);
System.exit(1);
this.exit(1);
} catch (JaxenException e) {
logger.error(e.getMessage(), e);
System.exit(1);
this.exit(1);
} finally {
logger.debug("Total execution took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
String forcefail = config.getString(OPTION_IS_FORCEFAILENABLED, "");
if(forcefail.length()>0) {
logger.warn("Force fail is active. All commits will be blocked.");
System.exit(1);
this.exit(1);
}
}
490,7 → 529,7
.getDocument().getOMDocumentElement();
} catch (FileNotFoundException e1) {
logger.error(String.format("Could not load XML event template from file '%s'.", eventtemplate), e1);
System.exit(1);
this.exit(1);
}
nss = readConfPropertyAsString(OPTION_EVENTNAMESPACE, "http://www.eclipse.org/alf/schema/EventBase/1", true, null);
final String marker_logmessage = readConfPropertyAsString(OPTION_MARKER_LOGMESSAGE, "@@logmessage@@", true, null);
522,9 → 561,25
}
private boolean verify(List<String> issues, boolean isTrace) {
private boolean verify(List<String> issues, boolean isTrace) throws MalformedURLException {
for(String issueid : issues) {
TTItemList items = getTTItems(issueid, isTrace);
if(items == null) {
return false;
}
}
return true;
}
private TTItemList getTTItems(String issueid, boolean isTrace) throws MalformedURLException {
long startTime = System.currentTimeMillis();
/* -- */
Sbmappservices72 ss = new Sbmappservices72(ClassLoader.getSystemResource("sbmappservices72.wsdl") );
logger.debug("Total execution of sbmappservices72 wsdl read took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
Sbmappservices72PortType port = ss.getSbmappservices72();
Client client = ClientProxy.getClient(port);
535,7 → 590,9
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
/* -- */
logger.debug("Total execution of sbmappservices72 initialisation took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
ObjectFactory fac = new ObjectFactory();
Auth auth = fac.createAuth();
auth.setUserId(fac.createAuthUserId(sbm_user));
545,15 → 602,18
table.setDbName(fac.createTableIdentifierDbName(querytable));
MultipleResponseItemOptions options = fac.createMultipleResponseItemOptions();
options.setSections(SectionsOption.SECTIONS_NONE);
options.setSpecifiedSections(fac.createResponseItemOptionsSpecifiedSections("SECTION:FIXED"));
options.setSections(SectionsOption.SECTIONS_SPECIFIED);
for(String issue : issues) {
issue = issue.replaceAll("[^0-9]", "");
String queryWhereClause = "TS_ISSUEID = '"+issue+"'";
if(query!=null && query.length()>0) queryWhereClause = queryWhereClause + " And " + query;
logger.debug(String.format("Using query against table '%s'. Query where clause: '%s'", querytable, queryWhereClause ));
try {
TTItemList items = port.getItemsByQuery(auth, table, queryWhereClause, "", null, BigInteger.valueOf(1), options);
issueid = issueid.replaceAll("[^0-9]", "");
String queryWhereClause = "TS_ISSUEID = '"+issueid+"'";
if(query!=null && query.length()>0) queryWhereClause = queryWhereClause + " And " + query;
TTItemList items = null;
logger.debug(String.format("Using query against table '%s'. Query where clause: '%s'", querytable, queryWhereClause ));
try {
startTime = System.currentTimeMillis();
items = port.getItemsByQuery(auth, table, queryWhereClause, "", null, BigInteger.valueOf(1), options);
logger.debug("Total execution of sbmappservices72 GetItems took '"+(System.currentTimeMillis()-startTime)+"' milliseconds.");
//Marshaller m = JAXBContext.newInstance(TTItemList.class).createMarshaller();
//m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
561,23 → 621,35
logger.debug(String.format("Got Response from getItemsByQuery"));
if(items!=null) {
logger.debug(String.format("Verification query matched '%s' item(s) for issue '%s.'",items.getTotalCount(), issue));
logger.debug(String.format("Verification query matched '%s' item(s) for issue '%s.'",items.getTotalCount(), issueid));
}
if(items.getTotalCount().intValue()<=0) {
return false;
return null;
} else {
/* store internal ids (tableid:itemid) */
internalissues.add(items.getItem().get(0).getId().getValue().getTableIdItemId().getValue());
/* Store a map entry with internal id and title */
issues_titles.put(items.getItem().get(0).getId().getValue().getDisplayName().getValue(),
items.getItem().get(0).getTitle().getValue());
}
} catch (AEWebservicesFaultFault e) {
} catch (AEWebservicesFaultFault e) {
logger.debug("Web service fault: " + e.getFaultInfo());
} catch (Exception e) {
} catch (Exception e) {
logger.debug("Unknown Exception", e);
}
}
return true;
return items;
}
}
private void postCommitUpdate(File svnadmin, String repos, String locale, String encoding, String revision, String newmessage) {
SVNAdminExecutor exec = new SVNAdminExecutor(svnadmin, repos);
exec.setRev(revision);
exec.setMessage(newmessage);
exec.setEncoding(encoding);
exec.setLocale(locale);
exec.executeSVNAdmin(SVNAdminCommand.SETLOG);
}
 
private void addElement(String pattern, String newCdata, boolean wrapCDATA) throws JaxenException {
OMComment comment = findComment(pattern);
618,6 → 690,12
logger.warn("Comment '"+pattern+"' was not found in the XML template.");
return null;
}
private void exit(int errorCode) {
long endTime = System.currentTimeMillis();
logger.debug("Total execution took '"+(endTime-startTime)+"' milliseconds.");
System.exit(errorCode);
}
@SuppressWarnings("static-access")
private static Options getOptions() {
656,7 → 734,7
// automatically generate the help statement
HelpFormatter formatter = new HelpFormatter();
String header = "\nSVN-ALFEventEmitter " + VERSION +", a SVN hook implemented in Java to emit Eclipse ALFEvents on commit.\n\n";
String footer = "Please send bug reports to bru@brutex.de.\n(c)2013 Brian Rosenberger";
String footer = "Please send bug reports to bru@brutex.de.\n(c)2014 Brian Rosenberger";
formatter.printHelp("java -jar SVN-ALFEventEmitter", header, getOptions(), footer, true);
}