Search in sources :

Example 1 with MAPIType

use of org.apache.poi.hsmf.datatypes.Types.MAPIType in project poi by apache.

the class POIFSChunkParser method process.

/**
    * Creates a chunk, and gives it to its parent group 
    */
protected static void process(Entry entry, ChunkGroup grouping) {
    String entryName = entry.getName();
    Chunk chunk = null;
    // Is it a properties chunk? (They have special names)
    if (entryName.equals(PropertiesChunk.NAME)) {
        if (grouping instanceof Chunks) {
            // These should be the properties for the message itself
            chunk = new MessagePropertiesChunk(grouping);
        } else {
            // Will be properties on an attachment or recipient
            chunk = new StoragePropertiesChunk(grouping);
        }
    } else {
        // Check it's a regular chunk
        if (entryName.length() < 9) {
            // Name in the wrong format
            return;
        }
        if (!entryName.contains("_")) {
            // Name in the wrong format
            return;
        }
        // Split it into its parts
        int splitAt = entryName.lastIndexOf('_');
        String namePrefix = entryName.substring(0, splitAt + 1);
        String ids = entryName.substring(splitAt + 1);
        //  the form __<name>_<id><type>
        if (namePrefix.equals("Olk10SideProps") || namePrefix.equals("Olk10SideProps_")) {
            // This is some odd Outlook 2002 thing, skip
            return;
        } else if (splitAt <= entryName.length() - 8) {
        // In the right form for a normal chunk
        // We'll process this further in a little bit
        } else {
            // Underscores not the right place, something's wrong
            throw new IllegalArgumentException("Invalid chunk name " + entryName);
        }
        // Now try to turn it into id + type
        try {
            int chunkId = Integer.parseInt(ids.substring(0, 4), 16);
            int typeId = Integer.parseInt(ids.substring(4, 8), 16);
            MAPIType type = Types.getById(typeId);
            if (type == null) {
                type = Types.createCustom(typeId);
            }
            // Special cases based on the ID
            if (chunkId == MAPIProperty.MESSAGE_SUBMISSION_ID.id) {
                chunk = new MessageSubmissionChunk(namePrefix, chunkId, type);
            } else {
                // So, do the usual thing which is by type
                if (type == Types.BINARY) {
                    chunk = new ByteChunk(namePrefix, chunkId, type);
                } else if (type == Types.DIRECTORY) {
                    if (entry instanceof DirectoryNode) {
                        chunk = new DirectoryChunk((DirectoryNode) entry, namePrefix, chunkId, type);
                    }
                } else if (type == Types.ASCII_STRING || type == Types.UNICODE_STRING) {
                    chunk = new StringChunk(namePrefix, chunkId, type);
                } else {
                // Type of an unsupported type! Skipping... 
                }
            }
        } catch (NumberFormatException e) {
            // Name in the wrong format
            return;
        }
    }
    if (chunk != null) {
        if (entry instanceof DocumentNode) {
            DocumentInputStream inp = null;
            try {
                inp = new DocumentInputStream((DocumentNode) entry);
                chunk.readValue(inp);
                grouping.record(chunk);
            } catch (IOException e) {
                logger.log(POILogger.ERROR, "Error reading from part " + entry.getName() + " - " + e);
            } finally {
                if (inp != null)
                    inp.close();
            }
        } else {
            grouping.record(chunk);
        }
    }
}
Also used : StoragePropertiesChunk(org.apache.poi.hsmf.datatypes.StoragePropertiesChunk) Chunks(org.apache.poi.hsmf.datatypes.Chunks) AttachmentChunks(org.apache.poi.hsmf.datatypes.AttachmentChunks) RecipientChunks(org.apache.poi.hsmf.datatypes.RecipientChunks) NameIdChunks(org.apache.poi.hsmf.datatypes.NameIdChunks) DocumentNode(org.apache.poi.poifs.filesystem.DocumentNode) ByteChunk(org.apache.poi.hsmf.datatypes.ByteChunk) DirectoryNode(org.apache.poi.poifs.filesystem.DirectoryNode) DirectoryChunk(org.apache.poi.hsmf.datatypes.DirectoryChunk) MessagePropertiesChunk(org.apache.poi.hsmf.datatypes.MessagePropertiesChunk) IOException(java.io.IOException) ByteChunk(org.apache.poi.hsmf.datatypes.ByteChunk) PropertiesChunk(org.apache.poi.hsmf.datatypes.PropertiesChunk) StringChunk(org.apache.poi.hsmf.datatypes.StringChunk) Chunk(org.apache.poi.hsmf.datatypes.Chunk) DirectoryChunk(org.apache.poi.hsmf.datatypes.DirectoryChunk) StoragePropertiesChunk(org.apache.poi.hsmf.datatypes.StoragePropertiesChunk) MessagePropertiesChunk(org.apache.poi.hsmf.datatypes.MessagePropertiesChunk) MessageSubmissionChunk(org.apache.poi.hsmf.datatypes.MessageSubmissionChunk) DocumentInputStream(org.apache.poi.poifs.filesystem.DocumentInputStream) MessageSubmissionChunk(org.apache.poi.hsmf.datatypes.MessageSubmissionChunk) StringChunk(org.apache.poi.hsmf.datatypes.StringChunk) MAPIType(org.apache.poi.hsmf.datatypes.Types.MAPIType)

Example 2 with MAPIType

use of org.apache.poi.hsmf.datatypes.Types.MAPIType in project poi by apache.

the class PropertiesChunk method readProperties.

protected void readProperties(InputStream value) throws IOException {
    boolean going = true;
    while (going) {
        try {
            // Read in the header
            int typeID = LittleEndian.readUShort(value);
            int id = LittleEndian.readUShort(value);
            long flags = LittleEndian.readUInt(value);
            // Turn the Type and ID into helper objects
            MAPIType type = Types.getById(typeID);
            MAPIProperty prop = MAPIProperty.get(id);
            // Wrap properties we don't know about as custom ones
            if (prop == MAPIProperty.UNKNOWN) {
                prop = MAPIProperty.createCustom(id, type, "Unknown " + id);
            }
            if (type == null) {
                logger.log(POILogger.WARN, "Invalid type found, expected ", prop.usualType, " but got ", typeID, " for property ", prop);
                going = false;
                break;
            }
            // Sanity check the property's type against the value's type
            if (prop.usualType != type) {
                // Is it an allowed substitution?
                if (type == Types.ASCII_STRING && prop.usualType == Types.UNICODE_STRING || type == Types.UNICODE_STRING && prop.usualType == Types.ASCII_STRING) {
                // It's fine to go with the specified instead of the
                // normal
                } else if (prop.usualType == Types.UNKNOWN) {
                    // We don't know what this property normally is, but it
                    // has come
                    // through with a valid type, so use that
                    logger.log(POILogger.INFO, "Property definition for ", prop, " is missing a type definition, found a value with type ", type);
                } else {
                    // Oh dear, something has gone wrong...
                    logger.log(POILogger.WARN, "Type mismatch, expected ", prop.usualType, " but got ", type, " for property ", prop);
                    going = false;
                    break;
                }
            }
            // TODO Detect if it is multi-valued, since if it is
            // then even fixed-length strings store their multiple
            // values in another chunk (much as variable length ones)
            // Work out how long the "data" is
            // This might be the actual data, or just a pointer
            // to another chunk which holds the data itself
            boolean isPointer = false;
            int length = type.getLength();
            if (!type.isFixedLength()) {
                isPointer = true;
                length = 8;
            }
            // Grab the data block
            byte[] data = new byte[length];
            IOUtils.readFully(value, data);
            // Skip over any padding
            if (length < 8) {
                byte[] padding = new byte[8 - length];
                IOUtils.readFully(value, padding);
            }
            // Wrap and store
            PropertyValue propVal = null;
            if (isPointer) {
                // We'll match up the chunk later
                propVal = new ChunkBasedPropertyValue(prop, flags, data);
            } else if (type == Types.NULL) {
                propVal = new NullPropertyValue(prop, flags, data);
            } else if (type == Types.BOOLEAN) {
                propVal = new BooleanPropertyValue(prop, flags, data);
            } else if (type == Types.SHORT) {
                propVal = new ShortPropertyValue(prop, flags, data);
            } else if (type == Types.LONG) {
                propVal = new LongPropertyValue(prop, flags, data);
            } else if (type == Types.LONG_LONG) {
                propVal = new LongLongPropertyValue(prop, flags, data);
            } else if (type == Types.FLOAT) {
                propVal = new FloatPropertyValue(prop, flags, data);
            } else if (type == Types.DOUBLE) {
                propVal = new DoublePropertyValue(prop, flags, data);
            } else if (type == Types.CURRENCY) {
                propVal = new CurrencyPropertyValue(prop, flags, data);
            } else if (type == Types.TIME) {
                propVal = new TimePropertyValue(prop, flags, data);
            } else // TODO Add in the rest of the types
            {
                propVal = new PropertyValue(prop, flags, data);
            }
            if (properties.get(prop) != null) {
                logger.log(POILogger.WARN, "Duplicate values found for " + prop);
            }
            properties.put(prop, propVal);
        } catch (BufferUnderrunException e) {
            // Invalid property, ended short
            going = false;
        }
    }
}
Also used : CurrencyPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.CurrencyPropertyValue) BooleanPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.BooleanPropertyValue) FloatPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.FloatPropertyValue) BufferUnderrunException(org.apache.poi.util.LittleEndian.BufferUnderrunException) LongPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue) LongLongPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.LongLongPropertyValue) LongLongPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.LongLongPropertyValue) DoublePropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.DoublePropertyValue) LongPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue) DoublePropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.DoublePropertyValue) TimePropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue) CurrencyPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.CurrencyPropertyValue) NullPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.NullPropertyValue) ShortPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.ShortPropertyValue) LongLongPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.LongLongPropertyValue) BooleanPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.BooleanPropertyValue) FloatPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.FloatPropertyValue) NullPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.NullPropertyValue) ShortPropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.ShortPropertyValue) MAPIType(org.apache.poi.hsmf.datatypes.Types.MAPIType) TimePropertyValue(org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue)

Example 3 with MAPIType

use of org.apache.poi.hsmf.datatypes.Types.MAPIType in project poi by apache.

the class MAPIAttribute method create.

/**
    * Parses a MAPI Properties TNEF Attribute, and returns
    *  the list of MAPI Attributes contained within it
    */
public static List<MAPIAttribute> create(TNEFAttribute parent) throws IOException {
    if (parent.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) {
    // Regular MAPI Properties, normally on the message
    } else if (parent.getProperty() == TNEFProperty.ID_ATTACHMENT) {
    // MAPI Properties for an attachment
    } else {
        // Something else, oh dear...
        throw new IllegalArgumentException("Can only create from a MAPIProperty attribute, " + "instead received a " + parent.getProperty() + " one");
    }
    ByteArrayInputStream inp = new ByteArrayInputStream(parent.getData());
    // First up, get the number of attributes
    int count = LittleEndian.readInt(inp);
    List<MAPIAttribute> attrs = new ArrayList<MAPIAttribute>();
    // Now, read each one in in turn
    for (int i = 0; i < count; i++) {
        int typeAndMV = LittleEndian.readUShort(inp);
        int id = LittleEndian.readUShort(inp);
        // Is it either Multi-Valued or Variable-Length?
        boolean isMV = false;
        boolean isVL = false;
        int typeId = typeAndMV;
        if ((typeAndMV & Types.MULTIVALUED_FLAG) != 0) {
            isMV = true;
            typeId -= Types.MULTIVALUED_FLAG;
        }
        if (typeId == Types.ASCII_STRING.getId() || typeId == Types.UNICODE_STRING.getId() || typeId == Types.BINARY.getId() || typeId == Types.DIRECTORY.getId()) {
            isVL = true;
        }
        // Turn the type ID into a strongly typed thing
        MAPIType type = Types.getById(typeId);
        if (type == null) {
            type = Types.createCustom(typeId);
        }
        // If it's a named property, rather than a standard
        //  MAPI property, grab the details of it
        MAPIProperty prop = MAPIProperty.get(id);
        if (id >= 0x8000 && id <= 0xFFFF) {
            byte[] guid = new byte[16];
            IOUtils.readFully(inp, guid);
            int mptype = LittleEndian.readInt(inp);
            // Get the name of it
            String name;
            if (mptype == 0) {
                // It's based on a normal one
                int mpid = LittleEndian.readInt(inp);
                MAPIProperty base = MAPIProperty.get(mpid);
                name = base.name;
            } else {
                // Custom name was stored
                int mplen = LittleEndian.readInt(inp);
                byte[] mpdata = new byte[mplen];
                IOUtils.readFully(inp, mpdata);
                name = StringUtil.getFromUnicodeLE(mpdata, 0, (mplen / 2) - 1);
                skipToBoundary(mplen, inp);
            }
            // Now create
            prop = MAPIProperty.createCustom(id, type, name);
        }
        if (prop == MAPIProperty.UNKNOWN) {
            prop = MAPIProperty.createCustom(id, type, "(unknown " + Integer.toHexString(id) + ")");
        }
        // Now read in the value(s)
        int values = 1;
        if (isMV || isVL) {
            values = LittleEndian.readInt(inp);
        }
        for (int j = 0; j < values; j++) {
            int len = getLength(type, inp);
            byte[] data = new byte[len];
            IOUtils.readFully(inp, data);
            skipToBoundary(len, inp);
            // Create
            MAPIAttribute attr;
            if (type == Types.UNICODE_STRING || type == Types.ASCII_STRING) {
                attr = new MAPIStringAttribute(prop, typeId, data);
            } else if (type == Types.APP_TIME || type == Types.TIME) {
                attr = new MAPIDateAttribute(prop, typeId, data);
            } else if (id == MAPIProperty.RTF_COMPRESSED.id) {
                attr = new MAPIRtfAttribute(prop, typeId, data);
            } else {
                attr = new MAPIAttribute(prop, typeId, data);
            }
            attrs.add(attr);
        }
    }
    // All done
    return attrs;
}
Also used : ArrayList(java.util.ArrayList) ByteArrayInputStream(java.io.ByteArrayInputStream) MAPIType(org.apache.poi.hsmf.datatypes.Types.MAPIType) MAPIProperty(org.apache.poi.hsmf.datatypes.MAPIProperty)

Aggregations

MAPIType (org.apache.poi.hsmf.datatypes.Types.MAPIType)3 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 AttachmentChunks (org.apache.poi.hsmf.datatypes.AttachmentChunks)1 ByteChunk (org.apache.poi.hsmf.datatypes.ByteChunk)1 Chunk (org.apache.poi.hsmf.datatypes.Chunk)1 Chunks (org.apache.poi.hsmf.datatypes.Chunks)1 DirectoryChunk (org.apache.poi.hsmf.datatypes.DirectoryChunk)1 MAPIProperty (org.apache.poi.hsmf.datatypes.MAPIProperty)1 MessagePropertiesChunk (org.apache.poi.hsmf.datatypes.MessagePropertiesChunk)1 MessageSubmissionChunk (org.apache.poi.hsmf.datatypes.MessageSubmissionChunk)1 NameIdChunks (org.apache.poi.hsmf.datatypes.NameIdChunks)1 PropertiesChunk (org.apache.poi.hsmf.datatypes.PropertiesChunk)1 BooleanPropertyValue (org.apache.poi.hsmf.datatypes.PropertyValue.BooleanPropertyValue)1 CurrencyPropertyValue (org.apache.poi.hsmf.datatypes.PropertyValue.CurrencyPropertyValue)1 DoublePropertyValue (org.apache.poi.hsmf.datatypes.PropertyValue.DoublePropertyValue)1 FloatPropertyValue (org.apache.poi.hsmf.datatypes.PropertyValue.FloatPropertyValue)1 LongLongPropertyValue (org.apache.poi.hsmf.datatypes.PropertyValue.LongLongPropertyValue)1 LongPropertyValue (org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue)1