/*
* This source is part of the
* _____ ___ ____
* __ / / _ \/ _ | / __/___ _______ _
* / // / , _/ __ |/ _/_/ _ \/ __/ _ `/
* \___/_/|_/_/ |_/_/ (_)___/_/ \_, /
* /___/
* repository.
*
* Copyright (C) 2013-2015 Carmen Alvarez (c@rmen.ca)
*
* 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 ca.rmen.android.networkmonitor.app.dbops.backend.export;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import ca.rmen.android.networkmonitor.Constants;
import ca.rmen.android.networkmonitor.R;
import ca.rmen.android.networkmonitor.app.prefs.NetMonPreferences;
import ca.rmen.android.networkmonitor.app.prefs.NetMonPreferences.CellIdFormat;
import ca.rmen.android.networkmonitor.provider.NetMonColumns;
import ca.rmen.android.networkmonitor.util.Log;
/**
* Create the appropriate Formatter instance depending on the formatter style.
*/
public class FormatterFactory {
private static final String TAG = Constants.TAG + FormatterFactory.class.getSimpleName();
public enum FormatterStyle {
DEFAULT, XML
}
/**
* @return the {@link Formatter} which will format for the given {@link FormatterStyle}.
*/
public static Formatter getFormatter(FormatterStyle formatterStyle, Context context) {
switch (formatterStyle) {
case XML:
return new XMLFormatter(context);
default:
return new DefaultFormatter(context);
}
}
/**
* This formats values with a format which is common to all export types.
*/
private static class DefaultFormatter implements Formatter {
public final SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss", Locale.US);
private final CellIdFormat mCellIdFormat;
private final Context mContext;
public DefaultFormatter(Context context) {
mContext = context;
mCellIdFormat = NetMonPreferences.getInstance(context).getCellIdFormat();
Log.v(TAG, "Constructor: cellIdFormat = " + mCellIdFormat);
}
/**
* @return a non-null String representation of the value at the given column and current Cursor row.
*/
@Override
public String format(Cursor c, int columnIndex) {
String result;
String columnName = c.getColumnName(columnIndex);
// Format timestamps
if (NetMonColumns.TIMESTAMP.equals(columnName)) {
long timestamp = c.getLong(columnIndex);
Date date = new Date(timestamp);
result = mDateFormat.format(date);
}
// Format cell ids
else if (NetMonColumns.CDMA_CELL_BASE_STATION_ID.equals(columnName) || NetMonColumns.CDMA_CELL_NETWORK_ID.equals(columnName)
|| NetMonColumns.CDMA_CELL_SYSTEM_ID.equals(columnName) || NetMonColumns.GSM_FULL_CELL_ID.equals(columnName)
|| NetMonColumns.GSM_SHORT_CELL_ID.equals(columnName) || NetMonColumns.GSM_CELL_LAC.equals(columnName)
|| NetMonColumns.GSM_RNC.equals(columnName)) {
result = c.getString(columnIndex);
if (mCellIdFormat != CellIdFormat.DECIMAL) {
if (!TextUtils.isEmpty(result)) {
try {
long cellId = Long.parseLong(result);
String cellIdHex = Long.toHexString(cellId);
if (mCellIdFormat == CellIdFormat.HEX) result = cellIdHex;
else
result = cellId + " (" + cellIdHex + ")";
} catch (NumberFormatException e) {
// Can't read the cell id as a hex number: just display the raw value.
}
}
}
}
// Latitude and longitude are stored in the DB with large precision,
// but this precision is lost if we retrieve them with getString().
else if (NetMonColumns.DEVICE_LATITUDE.equals(columnName)
|| NetMonColumns.DEVICE_LONGITUDE.equals(columnName)) {
double value = c.getDouble(columnIndex);
result = String.valueOf(value);
if ("0.0".equals(result)) result = "";
}
// bytes
else if (NetMonColumns.MOST_CONSUMING_APP_BYTES.equals(columnName)) {
long bytes = c.getLong(columnIndex);
if (bytes > 0) {
result = android.text.format.Formatter.formatShortFileSize(mContext, bytes);
} else {
result = "";
}
}
// Anything else: just return the raw value as a string
else {
result = c.getString(columnIndex);
}
// Make sure we don't return null.
if (result == null) result = "";
return result;
}
}
/**
* This does everything the {@link DefaultFormatter} does, and also makes sure certain text fields have special characters escaped properly for XML.
*/
private static class XMLFormatter extends DefaultFormatter {
private final List<String> mTextColumnNames;
public XMLFormatter(Context context) {
super(context);
String[] textColumns = context.getResources().getStringArray(R.array.text_columns);
mTextColumnNames = Arrays.asList(textColumns);
}
/**
* @return a non-null String representation of the value at the given column and current Cursor row, suitable for XML.
*/
@Override
public String format(Cursor c, int columnIndex) {
String result = super.format(c, columnIndex);
String columnName = c.getColumnName(columnIndex);
// If this is a field which can contain free text, let's make sure special characters are escaped for XML.
if (mTextColumnNames.contains(columnName)) {
result = result.replaceAll("&", "&");
result = result.replaceAll("<", "<");
result = result.replaceAll(">", ">");
}
return result;
}
}
}