Java tutorial
/* * Copyright (c) 2009 Haefelinger IT * * 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 it.haefelinger.flaka.util; import java.io.File; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; import org.apache.commons.httpclient.params.HttpMethodParams; /** * * @author merzedes * @since 1.0 */ public class HttpUpload { // protected static final Pattern REGEX_P; // protected static final Pattern FSIZE_P; protected static final Pattern SUBMI_P; // protected static String DEPOTBASE; protected static String ENDPOINT; protected static String TIMEOUT; protected static String TESTONLY; protected static String USER; protected static String PASSWD; protected Properties param = new Properties(); protected boolean debug = false; public HttpUpload() { reset(); } static { /* default timeout */ TIMEOUT = "5000"; /* 5 seconds */ /* default endpoint */ ENDPOINT = "http://haefelingerit.net/upload"; /* default test mode */ TESTONLY = "false"; /* default test mode */ USER = "alibaba"; /* default test mode */ PASSWD = "sesame"; SUBMI_P = Pattern .compile("(?:Accepted into depot|Submission would have been stored) as" + "\\s+([^\\s<]+)"); } public void reset() { this.param.clear(); set("testonly", TESTONLY); set("endpoint", ENDPOINT); set("timeout", TIMEOUT); set("testonly", TESTONLY); set("user", USER); set("passwd", PASSWD); } /** * Get value of attribute */ public String get(String name, String otherwise) { return this.param.getProperty(name, otherwise); } public String set(String name, String value) { String before; before = this.param.getProperty(name); if (value != null) { this.param.put(name, value); } else { /* remove key */ if (before != null) this.param.remove(name); } return before; } protected static void syslog(String s) { System.err.println(s); System.err.flush(); } public void setDebug(boolean b) { this.debug = b; HttpUpload.debug(b); } static protected void debug(boolean b) { /* set debug properties */ System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire.header", b ? "debug" : "info"); System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", b ? "debug" : "info"); } static private String getp(String p) { String s = System.getProperties().getProperty(p); if (s == null && !p.equals("httpupload.debug")) { System.err.println("error: required property `" + p + "' not set."); System.exit(1); } return s != null ? s.trim() : null; } static private String getp(String p, String otherwise) { String s = System.getProperties().getProperty(p); return (s == null) ? otherwise : s.trim(); } private String passwd() { return get("passwd", HttpUpload.PASSWD); } private String user() { return get("user", HttpUpload.USER); } static private FilePart filepart(File file) { FilePart p = null; try { p = new FilePart("jarfile", file); } catch (Exception e) { System.err.println("error reading loc `" + file.getName() + "'."); System.exit(1); } return p; } private void setError(String msg) { set("errmsg", msg); } public String getError() { return get("errmsg", null); } protected static void xmlattr(StringBuilder buf, String key, String val) { if (buf != null && key != null && val != null && val.matches("\\s*") == false) { buf.append(" "); buf.append(key); buf.append("=\""); buf.append(val); // tbd: escaple non XML chars here .. buf.append("\""); } } protected static void xmldata(StringBuilder buf, String elm, String val) { if (buf != null && elm != null && val != null && val.matches("\\s*") == false) { buf.append("<"); buf.append(elm); buf.append("><![CDATA["); buf.append(val); buf.append("]]></"); buf.append(elm); buf.append(">"); } } protected static String getResponseFrom(HttpMethod meth) { String r = null; try { r = meth.getResponseBodyAsString(); } catch (Exception e) { syslog("error reading HTTP response .." + e.getMessage()); } if (r == null) { syslog("* empty response seen .."); r = ""; } return r; } /** * Evaluate whether uploading went well or failed. * * A upload on Jdepot may fail cause a connection could not be established or * cause there was an application specific problem (like artifact exits * already or Manifest does not contain required or wrong attributes). * * @param meth * not null * @return true if all went well */ protected boolean eval(HttpMethod meth) { Matcher regex; String response = null; StringBuilder buf = new StringBuilder(""); String errmsg = null; String errtyp = null; // no error buf.append("<upload"); xmlattr(buf, "testonly", get("testonly", TESTONLY)); xmlattr(buf, "endpoint", get("endpoint", ENDPOINT)); xmlattr(buf, "timeout", get("timeout", TIMEOUT)); xmlattr(buf, "user", get("user", USER)); xmlattr(buf, "loc", get("filepath", null)); xmlattr(buf, "size", get("filesize", null)); /* If there was already an error, handle it now */ if (getError() != null) { syslog(getError()); /* must be a transport error at this point */ xmlattr(buf, "error", "transport-error"); buf.append(">"); xmldata(buf, "error", errmsg); buf.append("</upload>"); set("xmlbuf", buf.toString()); return false; } /* Handle any HTTP error */ if (meth.getStatusCode() / 100 != 2) { int stat; String line; stat = meth.getStatusCode(); line = meth.getStatusLine().toString(); errmsg = line + " [" + HttpStatusText.explain(stat) + "]"; setError(errmsg); xmlattr(buf, "error", "http-error"); buf.append("</upload>"); xmldata(buf, "error", errmsg); set("xmlbuf", buf.toString()); return false; } /* Fetch response text from server and run a check */ response = getResponseFrom(meth); /* save response for later usage */ this.set("resbuf", response); /* * We assume that everything went well, if respone text contains an * acceptance message. */ regex = SUBMI_P.matcher(response); /* do we have a confirmation message? */ if (regex.find() == false) { // scan for errors? No - this should be handled on another layer. errtyp = "storage-error"; errmsg = "unknown storage error"; this.setError(errmsg); xmlattr(buf, "error", errtyp); buf.append(">"); xmldata(buf, "error", errmsg); /* wrap entire response in any case */ xmldata(buf, "cdata", response); buf.append("</upload>"); set("xmlbuf", buf.toString()); return false; } /* Finally it's looking good ... */ String g1 = regex.group(1); xmlattr(buf, "href", g1); buf.append(">"); /* wrap entire response in any case */ xmldata(buf, "cdata", response); /* finish */ buf.append("</upload>"); set("xmlbuf", buf.toString()); return true; } protected void setcred(HttpClient client) { AuthScope scope; UsernamePasswordCredentials creds; scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT); creds = new UsernamePasswordCredentials(user(), passwd()); client.getState().setCredentials(scope, creds); } protected void settimeout(HttpClient client) { String s = get("timeout", HttpUpload.TIMEOUT); try { int timeout; timeout = Integer.parseInt(s); /* set default timeout */ client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout); } catch (Exception e) { syslog("* unable to set standard connection timeout to `" + s + "'."); } } protected boolean exec(HttpMethod meth) { HttpClient client; boolean rc = false; /* exec http method */ try { client = new HttpClient(); settimeout(client); setcred(client); client.executeMethod(meth); rc = (meth.getStatusCode() / 100) == 2; if (rc == false) { setError(meth.getStatusLine().toString()); } } catch (java.net.UnknownHostException ex) { set("errmsg", "unable to resolve host `" + ex.getMessage() + "'."); } catch (Exception ex) { setError(ex.getClass().getName() + " " + ex.getMessage()); if (this.debug) { System.err.println("*** excepting seen while uploading .."); ex.printStackTrace(System.err); System.err.println("<<*>>"); } } return rc; } public boolean upload() { File file = null; String endpoint = get("endpoint", HttpUpload.ENDPOINT); String testonly = get("testonly", HttpUpload.TESTONLY); String timeout = get("timeout", HttpUpload.TIMEOUT); String filepath = get("filepath", null); String logpath = get("logpath", null); String standard = get("standard", "1.0"); syslog("endpoint: " + endpoint); syslog("testonly: " + testonly); syslog("timeouts: " + timeout); syslog("filepath: " + filepath); syslog("logpath : " + logpath); syslog("standard: " + standard); PostMethod filePost = null; boolean rc; try { /* new game */ rc = false; setError(null); set("logmsg", ""); if (testonly == null || testonly.matches("\\s*false\\s*")) { testonly = "x-do-not-test"; } else { testonly = "test"; } if (filepath == null || filepath.matches("\\s*")) { set("logmsg", "empty property `filepath', nothing to do."); return true; } /* loc to upload */ file = new File(filepath); if (file.exists() == false) { setError("loc `" + file.getPath() + "' does not exist."); return false; } if (file.isFile() == false) { setError("loc `" + file.getPath() + "' exists but not a loc."); return false; } if (file.canRead() == false) { setError("loc `" + file.getPath() + "' can't be read."); return false; } set("filesize", "" + file.length()); /* create HTTP method */ filePost = new PostMethod(endpoint); Part[] parts = { new StringPart(testonly, "(opaque)"), filepart(file) }; filePost.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false); filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams())); /* execute method */ rc = exec(filePost) && eval(filePost); } finally { /* release resources in just any case */ if (filePost != null) filePost.releaseConnection(); } return rc; } public static void main(String[] args) { HttpUpload httpclient = null; if (args.length <= 0) { System.err.println("usage: <prog> loc [loc ..]"); System.exit(1); } debug(true); httpclient = new HttpUpload(); httpclient.set("endpoint", getp("httpupload.endpoint")); httpclient.set("category", getp("httpupload.category")); httpclient.set("testonly", getp("httpupload.testonly", "false")); httpclient.set("timeout", getp("httpupload.timeout")); httpclient.set("logpath", getp("httpupload.logpath")); httpclient.set("user", getp("httpupload.user")); httpclient.set("passwd", getp("httpupload.passwd")); if (getp("httpupload.debug") != null) debug(true); for (int i = 0; i < args.length; ++i) { httpclient.set("filepath", args[i]); syslog("uploading loc `" + args[i] + "'.."); if (!httpclient.upload()) { syslog("upload failed `" + httpclient.getError() + "'"); } else { System.out.println(httpclient.get("xmlbuf", "")); } } return; } }