/*
* Copyright 2010 Kevin Gaudin
*
* 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 org.acra.sender;
import static org.acra.ACRA.LOG_TAG;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.acra.ACRA;
import org.acra.CrashReportData;
import org.acra.ReportField;
import org.acra.annotation.ReportsCrashes;
import org.acra.util.HttpUtils;
import android.net.Uri;
import android.util.Log;
/**
* <p>
* The {@link ReportSender} used by ACRA when {@link ReportsCrashes#formUri()}
* has been defined in order to post crash data to a custom server-side data
* collection script. It sends all data in a POST request with parameters named
* with easy to understand names (basically a string conversion of
* {@link ReportField} enum values) or based on your own conversion Map from
* {@link ReportField} values to String.
* </p>
*
* <p>
* To use specific POST parameter names, you can provide your own report fields
* mapping scheme:
* </p>
*
* <pre>
* @ReportsCrashes(...)
* public class myApplication extends Application {
*
* public void onCreate() {
* ACRA.init(this);
* Map<ReportField, String> mapping = new HashMap<ReportField, String>();
* mapping.put(ReportField.APP_VERSION_CODE, "myAppVerCode');
* mapping.put(ReportField.APP_VERSION_NAME, "myAppVerName');
* //...
* mapping.put(ReportField.USER_EMAIL, "userEmail');
* // remove any default report sender
* ErrorReporter.getInstance().removeAllReportSenders();
* // create your own instance with your specific mapping
* ErrorReporter.getInstance().addReportSender(new ReportSender("http://my.domain.com/reports/receiver.py", mapping));
*
*
* super.onCreate();
* }
* }
* </pre>
*
* @author Kevin Gaudin
*
*/
public class HttpPostSender implements ReportSender {
private Uri mFormUri = null;
private Map<ReportField, String> mMapping = null;
/**
* <p>
* Create a new HttpPostSender instance.
* </p>
*
* @param formUri
* The URL of your server-side crash report collection script.
* @param mapping
* If null, POST parameters will be named with
* {@link ReportField} values converted to String with
* .toString(). If not null, POST parameters will be named with
* the result of mapping.get(ReportField.SOME_FIELD);
*/
public HttpPostSender(String formUri, Map<ReportField, String> mapping) {
mFormUri = Uri.parse(formUri);
mMapping = mapping;
}
@Override
public void send(CrashReportData report) throws ReportSenderException {
try {
URL reportUrl;
Map<String, String> finalReport = remap(report);
reportUrl = new URL(mFormUri.toString());
Log.d(LOG_TAG, "Connect to " + reportUrl.toString());
HttpUtils.doPost(finalReport, reportUrl, ACRA.getConfig().formUriBasicAuthLogin(), ACRA.getConfig()
.formUriBasicAuthPassword());
} catch (Exception e) {
throw new ReportSenderException("Error while sending report to Http Post Form.", e);
}
}
private Map<String, String> remap(Map<ReportField, String> report) {
Map<String, String> finalReport = new HashMap<String, String>(report.size());
ReportField[] fields = ACRA.getConfig().customReportContent();
if(fields.length == 0) {
fields = ACRA.DEFAULT_REPORT_FIELDS;
}
for (ReportField field : fields) {
if (mMapping == null || mMapping.get(field) == null) {
finalReport.put(field.toString(), report.get(field));
} else {
finalReport.put(mMapping.get(field), report.get(field));
}
}
return finalReport;
}
}