package lancs.mobilemedia.core.util; import java.io.IOException; import java.io.InputStream; import lancs.mobilemedia.core.ui.datamodel.MediaData; import lancs.mobilemedia.lib.exceptions.ImagePathNotValidException; import lancs.mobilemedia.lib.exceptions.InvalidArrayFormatException; import lancs.mobilemedia.lib.exceptions.InvalidImageDataException; import lancs.mobilemedia.lib.exceptions.InvalidImageFormatException; /** * @author trevor This is a utility class. It performs conversions between Image * objects and byte arrays, and Image metadata objects and byte arrays. * Byte arrays are the main format for storing data in RMS, and for * sending data over the wire. */ public class MediaUtil { // Delimiter used in record store data to separate fields in a string. protected static final String DELIMITER = "*"; // [NC] Changed in the scenario 07: to support extension of the method getMediaInfoFromBytes protected int endIndex = 0; /** * This method reads an Image from an Input Stream and converts it from a * standard image file format into a byte array, so that it can be * transported over wireless protocols such as SMS * * @throws ImagePathNotValidException * @throws InvalidImageFormatException */ public byte[] readMediaAsByteArray(String mediaFile) throws ImagePathNotValidException, InvalidImageFormatException { byte bArray[] = new byte[1000]; // Read an Image into a byte array // Required to transfer images over SMS InputStream is = null; try { is = (InputStream) this.getClass().getResourceAsStream(mediaFile); } catch (Exception e) { throw new ImagePathNotValidException( "Path not valid for this media:"+mediaFile); } int i, len = 0; byte bArray2[]; byte b[] = new byte[1]; try { while (is.read(b) != -1) { if (len + 1 >= bArray.length) { bArray2 = new byte[bArray.length]; // Transfer all data from old array to temp array for (i = 0; i < len; i++) bArray2[i] = bArray[i]; bArray = new byte[bArray2.length + 500]; // Re-Copy contents back into new bigger array for (i = 0; i < len; i++) bArray[i] = bArray2[i]; } // Set the size to be exact bArray[len] = b[0]; len++; } is.close(); } catch (IOException e1) { throw new InvalidImageFormatException( "The file "+mediaFile+" does not have a correct format"); } catch(NullPointerException e2){ throw new ImagePathNotValidException( "Path not valid for this file:"+mediaFile); } return bArray; } /** * * Convert the byte array from a retrieved RecordStore record into the * ImageInfo ((renamed ImageData) object Order of the string will look like * this: <recordId>*<foreignRecordId>*<labelName>*<imageLabel> Depending * on the optional features, additional fields may be: <phoneNum> * * @throws InvalidArrayFormatException */ public MediaData getMediaInfoFromBytes(byte[] bytes) throws InvalidArrayFormatException { try { String iiString = new String(bytes); // Track our position in the String using delimiters // Ie. Get chars from beginning of String to first Delim int startIndex = 0; endIndex = iiString.indexOf(DELIMITER); // Get recordID int value as String - everything before first // delimeter String intString = iiString.substring(startIndex, endIndex); // Get 'foreign' record ID corresponding to the image table startIndex = endIndex + 1; endIndex = iiString.indexOf(DELIMITER, startIndex); String fidString = iiString.substring(startIndex, endIndex); // Get Album name (recordstore) - next delimeter startIndex = endIndex + 1; endIndex = iiString.indexOf(DELIMITER, startIndex); String albumLabel = iiString.substring(startIndex, endIndex); startIndex = endIndex + 1; endIndex = iiString.indexOf(DELIMITER, startIndex); if (endIndex == -1) endIndex = iiString.length(); String imageLabel = ""; imageLabel = iiString.substring(startIndex, endIndex); // #ifdef includeFavourites // [EF] Favorite (Scenario 03) boolean favorite = false; startIndex = endIndex + 1; endIndex = iiString.indexOf(DELIMITER, startIndex); if (endIndex == -1) endIndex = iiString.length(); favorite = (iiString.substring(startIndex, endIndex)).equalsIgnoreCase("true"); // #endif // #ifdef includeSorting // [EF] Number of Views (Scenario 02) startIndex = endIndex + 1; endIndex = iiString.indexOf(DELIMITER, startIndex); if (endIndex == -1) endIndex = iiString.length(); int numberOfViews = 0; try { numberOfViews = Integer.parseInt(iiString.substring(startIndex, endIndex)); } catch (RuntimeException e) { numberOfViews = 0; e.printStackTrace(); } // #endif Integer x = Integer.valueOf(fidString); MediaData ii = new MediaData(x.intValue(), albumLabel, imageLabel); // #ifdef includeFavourites ii.setFavorite(favorite); // #endif // #ifdef includeSorting ii.setNumberOfViews(numberOfViews); // #endif x = Integer.valueOf(intString); ii.setRecordId(x.intValue()); return ii; } catch (Exception e) { throw new InvalidArrayFormatException(); } } /** * * Convert the ImageInfo (renamed ImageData) object into bytes so we can * store it in RMS Order of the string will look like this: <recordId>*<foreignRecordId>*<labelName>*<imageLabel> * Depending on the optional features, additional fields may be: <phoneNum> * @throws InvalidImageDataException */ public byte[] getBytesFromMediaInfo(MediaData ii) throws InvalidImageDataException { // Take each String and get the bytes from it, separating fields with a // delimiter try { String byteString = new String(); // Convert the record ID for this record int i = ii.getRecordId(); Integer j = new Integer(i); byteString = byteString.concat(j.toString()); byteString = byteString.concat(DELIMITER); // Convert the 'Foreign' Record ID field for the corresponding Image // record store int i2 = ii.getForeignRecordId(); Integer j2 = new Integer(i2); byteString = byteString.concat(j2.toString()); byteString = byteString.concat(DELIMITER); // Convert the album name field byteString = byteString.concat(ii.getParentAlbumName()); byteString = byteString.concat(DELIMITER); // Convert the label (name) field byteString = byteString.concat(ii.getMediaLabel()); // #ifdef includeFavourites // [EF] Added in scenario 03 byteString = byteString.concat(DELIMITER); if (ii.isFavorite()) byteString = byteString.concat("true"); else byteString = byteString.concat("false"); // #endif // #ifdef includeSorting // [EF] Added in scenario 02 byteString = byteString.concat(DELIMITER); byteString = byteString.concat(""+ii.getNumberOfViews()); // #endif // Convert the phone number field return byteString.getBytes(); } catch (Exception e) { throw new InvalidImageDataException("The provided data are not valid"); } } }