123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.apache.poi.hsmf.datatypes;
-
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- import java.util.Map;
-
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
-
- /**
- * Collection of convenience chunks for the Recip(ient) part of an outlook file.
- *
- * If a message has multiple recipients, there will be several of these.
- */
- public final class RecipientChunks implements ChunkGroupWithProperties {
- private static final Logger LOG = LogManager.getLogger(RecipientChunks.class);
-
- public static final String PREFIX = "__recip_version1.0_#";
-
- public static final MAPIProperty RECIPIENT_NAME = MAPIProperty.DISPLAY_NAME;
- public static final MAPIProperty DELIVERY_TYPE = MAPIProperty.ADDRTYPE;
- public static final MAPIProperty RECIPIENT_EMAIL_ADDRESS = MAPIProperty.EMAIL_ADDRESS;
- public static final MAPIProperty RECIPIENT_SEARCH = MAPIProperty.SEARCH_KEY;
- public static final MAPIProperty RECIPIENT_SMTP_ADDRESS = MAPIProperty.SMTP_ADDRESS;
- public static final MAPIProperty RECIPIENT_DISPLAY_NAME = MAPIProperty.RECIPIENT_DISPLAY_NAME;
-
- /** Our 0 based position in the list of recipients */
- private int recipientNumber;
-
- /** TODO */
- private ByteChunk recipientSearchChunk;
- /**
- * The "name", which could be their name if an internal person, or their
- * email address if an external person
- */
- private StringChunk recipientNameChunk;
- /**
- * The email address of the recipient, which could be in SMTP or SEARCH
- * format, but isn't always present...
- */
- private StringChunk recipientEmailChunk;
- /**
- * The smtp destination email address of the recipient, but isn't always
- * present...
- */
- private StringChunk recipientSMTPChunk;
- /**
- * Normally EX or SMTP. Will generally affect where the email address ends
- * up.
- */
- private StringChunk deliveryTypeChunk;
- /**
- * The display name of the recipient. Normally seems to hold the same value
- * as in recipientNameChunk
- */
- private StringChunk recipientDisplayNameChunk;
- /**
- * Holds the fixed sized properties, and the pointers to the data of
- * variable sized ones
- */
- private PropertiesChunk recipientProperties;
-
- public RecipientChunks(String name) {
- recipientNumber = -1;
- int splitAt = name.lastIndexOf('#');
- if (splitAt > -1) {
- String number = name.substring(splitAt + 1);
- try {
- recipientNumber = Integer.parseInt(number, 16);
- } catch (NumberFormatException e) {
- LOG.atError().log("Invalid recipient number in name {}", name);
- }
- }
- }
-
- public int getRecipientNumber() {
- return recipientNumber;
- }
-
- public ByteChunk getRecipientSearchChunk() {
- return recipientSearchChunk;
- }
-
- public StringChunk getRecipientNameChunk() {
- return recipientNameChunk;
- }
-
- public StringChunk getRecipientEmailChunk() {
- return recipientEmailChunk;
- }
-
- public StringChunk getRecipientSMTPChunk() {
- return recipientSMTPChunk;
- }
-
- public StringChunk getDeliveryTypeChunk() {
- return deliveryTypeChunk;
- }
-
- public StringChunk getRecipientDisplayNameChunk() {
- return recipientDisplayNameChunk;
- }
-
- /**
- * Tries to find their name, in whichever chunk holds it.
- */
- public String getRecipientName() {
- if (recipientNameChunk != null) {
- return recipientNameChunk.getValue();
- }
- if (recipientDisplayNameChunk != null) {
- return recipientDisplayNameChunk.getValue();
- }
-
- // Can't find it
- return null;
- }
-
- /**
- * Tries to find their email address, in whichever chunk holds it given the
- * delivery type.
- */
- public String getRecipientEmailAddress() {
- // If we have this, it really has the email
- if (recipientSMTPChunk != null) {
- return recipientSMTPChunk.getValue();
- }
-
- // This might be a real email, or might be
- // in CN=... format
- if (recipientEmailChunk != null) {
- String email = recipientEmailChunk.getValue();
- int cne = email.indexOf("/CN=");
- if (cne < 0) {
- // Normal smtp address
- return email;
- } else {
- // /O=..../CN=em@ail
- return email.substring(cne + 4);
- }
- }
-
- // Might be in the name field, check there
- if (recipientNameChunk != null) {
- String name = recipientNameChunk.getValue();
- if (name.contains("@")) {
- // Strip leading and trailing quotes if needed
- if (name.startsWith("'") && name.endsWith("'")) {
- return name.substring(1, name.length() - 1);
- }
- return name;
- }
- }
-
- // Check the search chunk, see if it's
- // encoded as a SMTP destination in there.
- if (recipientSearchChunk != null) {
- String search = recipientSearchChunk.getAs7bitString();
- int idx = search.indexOf("SMTP:");
- if (idx >= 0) {
- return search.substring(idx + 5);
- }
- }
-
- // Can't find it
- return null;
- }
-
- /** Holds all the chunks that were found. */
- private final List<Chunk> allChunks = new ArrayList<>();
-
- @Override
- public Map<MAPIProperty, List<PropertyValue>> getProperties() {
- if (recipientProperties != null) {
- return recipientProperties.getProperties();
- } else {
- return Collections.emptyMap();
- }
- }
-
- public Chunk[] getAll() {
- return allChunks.toArray(new Chunk[0]);
- }
-
- @Override
- public Chunk[] getChunks() {
- return getAll();
- }
-
- /**
- * Called by the parser whenever a chunk is found.
- */
- @Override
- public void record(Chunk chunk) {
- try {
- if (chunk.getChunkId() == RECIPIENT_SEARCH.id) {
- // TODO - parse
- recipientSearchChunk = (ByteChunk) chunk;
- } else if (chunk.getChunkId() == RECIPIENT_NAME.id) {
- recipientDisplayNameChunk = (StringChunk) chunk;
- } else if (chunk.getChunkId() == RECIPIENT_DISPLAY_NAME.id) {
- recipientNameChunk = (StringChunk) chunk;
- } else if (chunk.getChunkId() == RECIPIENT_EMAIL_ADDRESS.id) {
- recipientEmailChunk = (StringChunk) chunk;
- } else if (chunk.getChunkId() == RECIPIENT_SMTP_ADDRESS.id) {
- recipientSMTPChunk = (StringChunk) chunk;
- } else if (chunk.getChunkId() == DELIVERY_TYPE.id) {
- deliveryTypeChunk = (StringChunk) chunk;
- } else if (chunk instanceof PropertiesChunk) {
- recipientProperties = (PropertiesChunk) chunk;
- }
- } catch (ClassCastException e) {
- throw new IllegalArgumentException("ChunkId and type of chunk did not match, had id " +
- chunk.getChunkId() + " and type of chunk: " + chunk.getClass(), e);
- }
-
- // And add to the main list
- allChunks.add(chunk);
- }
-
- @Override
- public void chunksComplete() {
- if (recipientProperties != null) {
- recipientProperties.matchVariableSizedPropertiesToChunks();
- } else {
- LOG.atWarn().log("Recipients Chunk didn't contain a list of properties!");
- }
- }
-
- /**
- * Orders by the recipient number.
- */
- public static class RecipientChunksSorter
- implements Comparator<RecipientChunks>, Serializable {
- @Override
- public int compare(RecipientChunks a, RecipientChunks b) {
- return Integer.compare(a.recipientNumber, b.recipientNumber);
- }
- }
- }
|