diff --git a/pom.xml b/pom.xml index f465f51..b45f98b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,9 +10,9 @@ jar - 4.32.0 + 4.32.0.avoid-reflection-in-zal -SNAPSHOT - 4.28.0 + 4.28.1.avoid-reflection-in-zal-SNAPSHOT UTF-8 2.15.4 1.0.15 @@ -706,39 +706,6 @@ - - com.coderplus.maven.plugins - copy-rename-maven-plugin - 1.0.1 - - - rename-DataExtractor - compile - - copy - - - - ${project.build.directory}/classes/com/zimbra/cs/redolog/op/DataExtractor.class - - ${project.build.directory}/classes/com/zimbra/cs/redolog/op/DataExtractor - - - - rename-VolumeBlobProxy - compile - - copy - - - - ${project.build.directory}/classes/com/zimbra/cs/store/file/VolumeBlobProxy.class - - ${project.build.directory}/classes/com/zimbra/cs/store/file/VolumeBlobProxy - - - - org.apache.maven.plugins maven-source-plugin @@ -778,10 +745,6 @@ org.openzal.zal.extension.ZalEntrypointImpl - - com/zimbra/cs/redolog/op/DataExtractor.class - com/zimbra/cs/store/file/VolumeBlobProxy.class - diff --git a/src/main/java/org/openzal/zal/BlobWrap.java b/src/main/java/org/openzal/zal/BlobWrap.java index 4285831..4824c48 100644 --- a/src/main/java/org/openzal/zal/BlobWrap.java +++ b/src/main/java/org/openzal/zal/BlobWrap.java @@ -20,7 +20,7 @@ package org.openzal.zal; -import com.zimbra.cs.store.file.VolumeBlobProxy; +import com.zimbra.cs.store.file.VolumeBlob; import com.zimbra.cs.store.file.VolumeMailboxBlob; import com.zimbra.cs.store.file.VolumeStagedBlob; import javax.annotation.Nonnull; @@ -55,9 +55,9 @@ public BlobWrap( { throw new RuntimeException("Cannot handle blob of type " + blob.getClass()); } - if (VolumeBlobProxy.isVolumeBlob(blob)) + if (VolumeBlobUtils.isVolumeBlob(blob)) { - volumeId = String.valueOf(new VolumeBlobProxy(blob).getVolumeId()); + volumeId = String.valueOf(new VolumeBlob((VolumeBlob) blob).getVolumeId()); } mVolumeId = volumeId; @@ -133,8 +133,7 @@ public BlobWrap setSize(long size) } @Override - public long getStoredFileSize() throws IOException - { + public long getStoredFileSize() { return mBlob.getFile().length(); } diff --git a/src/main/java/org/openzal/zal/Flag.java b/src/main/java/org/openzal/zal/Flag.java index 2702fb6..3d36d4e 100644 --- a/src/main/java/org/openzal/zal/Flag.java +++ b/src/main/java/org/openzal/zal/Flag.java @@ -20,9 +20,7 @@ package org.openzal.zal; -import java.lang.reflect.*; -import org.openzal.zal.log.ZimbraLog; import javax.annotation.Nonnull; @@ -68,40 +66,9 @@ public final class Flag extends Item public static int BITMASK_ARCHIVED = com.zimbra.cs.mailbox.Flag.BITMASK_ARCHIVED; public static int BITMASK_IN_DUMPSTER = com.zimbra.cs.mailbox.Flag.BITMASK_IN_DUMPSTER; - private static Method sFlagOf; - - static - { - try - { - Class partypes[] = new Class[1]; - partypes[0] = int.class; - - sFlagOf = com.zimbra.cs.mailbox.Flag.FlagInfo.class.getDeclaredMethod("of", partypes); - sFlagOf.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - static com.zimbra.cs.mailbox.Flag.FlagInfo of(int id) { - try - { - Object parameters[] = new Object[1]; - parameters[0] = id; - - return (com.zimbra.cs.mailbox.Flag.FlagInfo) sFlagOf.invoke(null, parameters); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } + return com.zimbra.cs.mailbox.Flag.FlagInfo.of(id); } public static int BITMASK_FROM_ME = com.zimbra.cs.mailbox.Flag.BITMASK_FROM_ME; diff --git a/src/main/java/org/openzal/zal/InternalOverrideBlobWithMailboxInfo.java b/src/main/java/org/openzal/zal/InternalOverrideBlobWithMailboxInfo.java index 3ad7c23..b4b0f1d 100644 --- a/src/main/java/org/openzal/zal/InternalOverrideBlobWithMailboxInfo.java +++ b/src/main/java/org/openzal/zal/InternalOverrideBlobWithMailboxInfo.java @@ -28,14 +28,17 @@ import java.io.IOException; import java.io.InputStream; -class InternalOverrideBlobWithMailboxInfo extends com.zimbra.cs.store.file.VolumeBlobProxy +import static org.openzal.zal.VolumeBlobUtils.VOLUME_BLOB_DEFAULT_FILE; +import static org.openzal.zal.VolumeBlobUtils.VOLUME_BLOB_DEFAULT_VOLUME_ID; + +class InternalOverrideBlobWithMailboxInfo extends com.zimbra.cs.store.file.VolumeBlob { private final Blob mBlob; private final String mVolumeId; public InternalOverrideBlobWithMailboxInfo(Blob blob) { - super(); + super(VOLUME_BLOB_DEFAULT_FILE, VOLUME_BLOB_DEFAULT_VOLUME_ID); mBlob = blob; mVolumeId = blob.getVolumeId(); } diff --git a/src/main/java/org/openzal/zal/InternalOverrideVolumeBlob.java b/src/main/java/org/openzal/zal/InternalOverrideVolumeBlob.java index 6f6abb3..87c2c22 100644 --- a/src/main/java/org/openzal/zal/InternalOverrideVolumeBlob.java +++ b/src/main/java/org/openzal/zal/InternalOverrideVolumeBlob.java @@ -20,7 +20,7 @@ package org.openzal.zal; -import com.zimbra.cs.store.file.VolumeBlobProxy; +import com.zimbra.cs.store.file.VolumeBlob; import org.apache.commons.io.IOUtils; import java.io.BufferedInputStream; @@ -29,14 +29,17 @@ import java.io.IOException; import java.io.InputStream; -class InternalOverrideVolumeBlob extends VolumeBlobProxy +import static org.openzal.zal.VolumeBlobUtils.VOLUME_BLOB_DEFAULT_FILE; +import static org.openzal.zal.VolumeBlobUtils.VOLUME_BLOB_DEFAULT_VOLUME_ID; + +class InternalOverrideVolumeBlob extends VolumeBlob { private final Blob mBlob; private final String mVolumeId; public InternalOverrideVolumeBlob(Blob blob) { - super(); + super(VOLUME_BLOB_DEFAULT_FILE, VOLUME_BLOB_DEFAULT_VOLUME_ID); mBlob = blob; mVolumeId = blob.getVolumeId(); } diff --git a/src/main/java/org/openzal/zal/Item.java b/src/main/java/org/openzal/zal/Item.java index 1e7be7a..d721541 100644 --- a/src/main/java/org/openzal/zal/Item.java +++ b/src/main/java/org/openzal/zal/Item.java @@ -25,7 +25,6 @@ import com.zimbra.cs.mailbox.MailItem; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,7 +35,6 @@ import org.openzal.zal.exceptions.NoSuchFolderException; import org.openzal.zal.exceptions.ZimbraException; import org.openzal.zal.lib.ZimbraVersion; -import org.openzal.zal.log.ZimbraLog; import org.openzal.zal.lucene.document.Document; import javax.annotation.Nonnull; @@ -60,9 +58,6 @@ public class Item implements Comparable public static final byte TYPE_MOUNTPOINT = 13; public static final byte TYPE_CHAT = 16; - // FIXME clone of Item.UnderlyingData.FIELD_INDEX_ID - public static final String FN_INDEX_ID = "idx"; - public Item(Object item) { mMailItem = (MailItem) Objects.requireNonNull(item); @@ -115,10 +110,10 @@ public static Item constructItem(@Nonnull Mailbox mbox, @Nonnull UnderlyingData try { return new Item( - MailItem.constructItem( - mbox.toZimbra(com.zimbra.cs.mailbox.Mailbox.class), - data.toZimbra(MailItem.UnderlyingData.class) - ) + MailItem.constructItem( + mbox.toZimbra(com.zimbra.cs.mailbox.Mailbox.class), + data.toZimbra(MailItem.UnderlyingData.class) + ) ); } catch (com.zimbra.common.service.ServiceException e) @@ -129,16 +124,16 @@ public static Item constructItem(@Nonnull Mailbox mbox, @Nonnull UnderlyingData @Nonnull public static Item constructItem(@Nonnull Mailbox mbox, @Nonnull UnderlyingData data, boolean skipCache) - throws ZimbraException + throws ZimbraException { try { return new Item( - MailItem.constructItem( - mbox.toZimbra(com.zimbra.cs.mailbox.Mailbox.class), - data.toZimbra(MailItem.UnderlyingData.class), - skipCache - ) + MailItem.constructItem( + mbox.toZimbra(com.zimbra.cs.mailbox.Mailbox.class), + data.toZimbra(MailItem.UnderlyingData.class), + skipCache + ) ); } catch( com.zimbra.common.service.ServiceException e ) @@ -155,7 +150,7 @@ public Mailbox getMailbox() public int getMailboxId() { - return (int) mMailItem.getMailboxId(); + return mMailItem.getMailboxId(); } public String getDigest() @@ -291,7 +286,7 @@ public String getBlobPath() throws IOException public static class CustomMetadata { - private MailItem.CustomMetadata mCustomMetadata; + private final MailItem.CustomMetadata mCustomMetadata; public CustomMetadata(Object meta) { @@ -381,7 +376,7 @@ public static class UnderlyingData public static final String FN_MOD_CONTENT = "modc"; public static final String FN_DATE_CHANGED = "dc"; - private MailItem.UnderlyingData mUnderlyingData; + private final MailItem.UnderlyingData mUnderlyingData; public UnderlyingData() { @@ -407,7 +402,7 @@ public UnderlyingData(Metadata metadata) } public void deserialize(Metadata metadata) - throws ServiceException + throws ServiceException { mUnderlyingData.deserialize(metadata.toZimbra(com.zimbra.cs.mailbox.Metadata.class)); } @@ -549,7 +544,7 @@ public static class Color public static final Color RED = new Color(0xFF0000L); public static final Color YELLOW = new Color(0xFFFF00L); - private com.zimbra.common.mailbox.Color mColor; + private final com.zimbra.common.mailbox.Color mColor; public Color(Object color) { @@ -602,7 +597,7 @@ public String getName() } public String getPath() - throws ZimbraException + throws ZimbraException { try { @@ -625,7 +620,7 @@ public int getParentId() } public InputStream getContentStream() - throws ZimbraException + throws ZimbraException { try { @@ -638,7 +633,7 @@ public InputStream getContentStream() } public byte[] getContent() - throws ZimbraException + throws ZimbraException { try { @@ -695,7 +690,7 @@ public String toString() } public boolean inTrash() - throws NoSuchFolderException + throws NoSuchFolderException { try { @@ -727,121 +722,33 @@ public boolean isUnread() return mMailItem.isUnread(); } - private static Method sDeserializeMethod; - - static - { - try - { - Class partypes[] = new Class[1]; - partypes[0] = com.zimbra.cs.mailbox.Metadata.class; - - sDeserializeMethod = MailItem.UnderlyingData.class.getDeclaredMethod("deserialize", partypes); - sDeserializeMethod.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - @Nonnull public static UnderlyingData decodeZimbraMetadata(@Nullable ZimbraVersion originVersion, final String encodedString) - throws ZimbraException + throws ZimbraException { - try - { - Metadata meta = new Metadata(encodedString); - - UnderlyingData underlyingData = new UnderlyingData(); - Object parameters[] = new Object[1]; - parameters[0] = meta.toZimbra(com.zimbra.cs.mailbox.Metadata.class); + Metadata meta = new Metadata(encodedString); - sDeserializeMethod.invoke( - underlyingData.toZimbra(MailItem.UnderlyingData.class), - parameters - ); + UnderlyingData underlyingData = new UnderlyingData(); + try { + com.zimbra.cs.mailbox.Metadata metadata = meta.toZimbra(com.zimbra.cs.mailbox.Metadata.class); + underlyingData.toZimbra(MailItem.UnderlyingData.class).deserialize(metadata); return underlyingData; - } - catch (Throwable ex) - { - throw new RuntimeException(ex); - } - } - - private static Method sSerializeMethod; - - static - { - try - { - Class partypes[] = new Class[0]; - sSerializeMethod = MailItem.UnderlyingData.class.getDeclaredMethod("serialize", partypes); - sSerializeMethod.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); + } catch (ServiceException e) { + throw ExceptionWrapper.wrap(e); } } @Nullable public String encodeZimbraMetadata() { - try - { - UnderlyingData underlyingData = getUnderlyingData(); - Object parameters[] = new Object[0]; - com.zimbra.cs.mailbox.Metadata meta = (com.zimbra.cs.mailbox.Metadata) sSerializeMethod.invoke( - underlyingData.toZimbra(MailItem.UnderlyingData.class), - parameters - ); - return meta.toString(); - } - catch (Throwable ex) - { - ZimbraLog.mailbox.warn("Exception: " + Utils.exceptionToString(ex)); - return null; - } - } - - private static Method sEncodeMetadata; - - static - { - try - { - Class partypes[] = {com.zimbra.cs.mailbox.Metadata.class}; - - sEncodeMetadata = MailItem.class.getDeclaredMethod("encodeMetadata", partypes); - sEncodeMetadata.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } + UnderlyingData underlyingData = getUnderlyingData(); + return underlyingData.toZimbra(MailItem.UnderlyingData.class).serialize().toString(); } @Nullable public String encodeSubmetadataForItemType() { - try - { - Object parameters[] = { new com.zimbra.cs.mailbox.Metadata() }; - com.zimbra.cs.mailbox.Metadata meta = (com.zimbra.cs.mailbox.Metadata) sEncodeMetadata.invoke( - mMailItem, - parameters - ); - return meta.toString(); - } - catch (Throwable ex) - { - ZimbraLog.mailbox.warn("Exception: " + Utils.exceptionToString(ex)); - return null; - } + return mMailItem.encodeMetadata(new com.zimbra.cs.mailbox.Metadata()).toString(); } public String[] getTags() diff --git a/src/main/java/org/openzal/zal/Mailbox.java b/src/main/java/org/openzal/zal/Mailbox.java index 5123a84..b1555c4 100644 --- a/src/main/java/org/openzal/zal/Mailbox.java +++ b/src/main/java/org/openzal/zal/Mailbox.java @@ -22,8 +22,6 @@ import com.zimbra.common.service.ServiceException; import com.zimbra.common.soap.SoapProtocol; -import com.zimbra.common.util.Pair; -import com.zimbra.cs.db.DbMailItem; import com.zimbra.cs.db.DbMailbox; import com.zimbra.cs.db.DbPool; import com.zimbra.cs.fb.FreeBusyQuery; @@ -39,17 +37,11 @@ import com.zimbra.cs.mailbox.Mailbox.DeleteBlobs; import com.zimbra.cs.mailbox.calendar.RecurId; import com.zimbra.cs.mailbox.util.TypedIdList; -import com.zimbra.cs.redolog.RedoLogManager; -import com.zimbra.cs.redolog.op.SetConfig; import com.zimbra.cs.service.FileUploadServlet.Upload; import com.zimbra.cs.service.mail.ItemActionHelper; import com.zimbra.cs.service.util.ItemId; import com.zimbra.cs.session.Session; -import java.util.Objects; import org.apache.commons.dbutils.DbUtils; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import org.openzal.zal.calendar.CalendarItemData; import org.openzal.zal.calendar.Invite; import org.openzal.zal.calendar.RecurrenceId; @@ -67,14 +59,14 @@ import org.openzal.zal.lib.ZimbraConnectionWrapper; import org.openzal.zal.lib.ZimbraDatabase; import org.openzal.zal.log.ZimbraLog; +import org.openzal.zal.redolog.RedoLogProvider; +import org.openzal.zal.redolog.op.RawSetConfig; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.mail.internet.MimeMessage; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -88,20 +80,14 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; -import org.openzal.zal.redolog.RedoLogProvider; -import org.openzal.zal.redolog.op.RawSetConfig; - -//import com.zimbra.cs.fb.FreeBusy; - - public class Mailbox { @Nonnull final private com.zimbra.cs.mailbox.Mailbox mMbox; @Nonnull private final MailboxIndex mIndex; - public static final int ID_AUTO_INCREMENT = com.zimbra.cs.mailbox.Mailbox.ID_AUTO_INCREMENT; public static final int ID_FOLDER_USER_ROOT = com.zimbra.cs.mailbox.Mailbox.ID_FOLDER_USER_ROOT; public static final int ID_FOLDER_INBOX = com.zimbra.cs.mailbox.Mailbox.ID_FOLDER_INBOX; public static final int ID_FOLDER_TRASH = com.zimbra.cs.mailbox.Mailbox.ID_FOLDER_TRASH; @@ -117,34 +103,12 @@ public class Mailbox public static final int ID_FOLDER_AUTO_CONTACTS = com.zimbra.cs.mailbox.Mailbox.ID_FOLDER_AUTO_CONTACTS; public static final int ID_FOLDER_IM_LOGS = com.zimbra.cs.mailbox.Mailbox.ID_FOLDER_IM_LOGS; public static final int ID_FOLDER_COMMENTS = 17; - public static final int ID_FOLDER_PROFILE = 18; private static final int HIGHEST_SYSTEM_ID = com.zimbra.cs.mailbox.Mailbox.HIGHEST_SYSTEM_ID; public static final int FIRST_USER_ID = com.zimbra.cs.mailbox.Mailbox.FIRST_USER_ID; private static final Set CREATE_CALENDAR_ITEM_ALLOWED_METHODS = new HashSet<>(Arrays.asList("PUBLISH", "REQUEST")); - private static Method sCreateDefaultFlags; - - static - { - try - { - sCreateDefaultFlags = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredMethod("createDefaultFlags"); - sCreateDefaultFlags.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - public MailboxMaintenance getMaintenance() - { - return new MailboxMaintenance(mMbox.getMaintenance()); - } - public long getSize() { return mMbox.getSize(); @@ -170,10 +134,10 @@ public void emptyFolder(@Nonnull OperationContext zContext, int folderId, boolea public MailboxData getMailboxData() { return new MailboxData( - getId(), - getSchemaGroupId(), - getAccountId(), - getIndexVolume() + getId(), + getSchemaGroupId(), + getAccountId(), + getIndexVolume() ); } @@ -199,8 +163,8 @@ public FakeMailbox(long id, String accountId, int schemaGroupId) @Nonnull private static MailboxData createMailboxMetadata( - @Nonnull - com.zimbra.cs.account.Account account + @Nonnull + com.zimbra.cs.account.Account account ) { MailboxData data = new MailboxData(); @@ -218,7 +182,7 @@ private static MailboxData createMailboxMetadata( data.recentMessages = -1; data.trackSync = -1; data.trackImap = false; - data.configKeys = new HashSet(); + data.configKeys = new HashSet<>(); return data; } @@ -226,7 +190,7 @@ private static MailboxData createMailboxMetadata( @Nonnull private static MailboxData createMailboxMetadata(int id, String accountId, int schemaGroupId) { - com.zimbra.cs.mailbox.Mailbox.MailboxData data = new com.zimbra.cs.mailbox.Mailbox.MailboxData(); + MailboxData data = new MailboxData(); data.id = id; data.schemaGroupId = schemaGroupId; data.accountId = accountId; @@ -241,7 +205,7 @@ private static MailboxData createMailboxMetadata(int id, String accountId, int s data.recentMessages = -1; data.trackSync = -1; data.trackImap = false; - data.configKeys = new HashSet(); + data.configKeys = new HashSet<>(); return data; } @@ -252,10 +216,10 @@ public void migrateContactGroup() try { com.zimbra.cs.mailbox.ContactGroup.MigrateContactGroup contactGroup = - new com.zimbra.cs.mailbox.ContactGroup.MigrateContactGroup(mMbox); + new com.zimbra.cs.mailbox.ContactGroup.MigrateContactGroup(mMbox); contactGroup.handle(); } - catch (com.zimbra.common.service.ServiceException ex) + catch (ServiceException ex) { throw ExceptionWrapper.wrap(ex); } @@ -276,7 +240,7 @@ public Mailbox(@Nullable Object mbox) public static Mailbox createFakeMailbox(@Nonnull Account realAccount) { return new Mailbox( - new FakeMailbox(realAccount.toZimbra(com.zimbra.cs.account.Account.class)) + new FakeMailbox(realAccount.toZimbra(com.zimbra.cs.account.Account.class)) ); } @@ -284,7 +248,7 @@ public static Mailbox createFakeMailbox(@Nonnull Account realAccount) public static Mailbox createFakeMailbox(long id, String accountId, int schemaGroupId) { return new Mailbox( - new FakeMailbox(id, accountId, schemaGroupId) + new FakeMailbox(id, accountId, schemaGroupId) ); } @@ -297,11 +261,11 @@ public T toZimbra(@Nonnull Class cls) public OperationContext newZimbraAdminContext() { return new OperationContext( - new com.zimbra.cs.mailbox.OperationContext( - new ProvisioningImp( - com.zimbra.cs.account.Provisioning.getInstance() - ).getZimbraUser().toZimbra(com.zimbra.cs.account.Account.class) - ,true) + new com.zimbra.cs.mailbox.OperationContext( + new ProvisioningImp( + com.zimbra.cs.account.Provisioning.getInstance() + ).getZimbraUser().toZimbra(com.zimbra.cs.account.Account.class) + ,true) ); } @@ -313,13 +277,13 @@ public com.zimbra.cs.mailbox.Mailbox getMailbox() @Nonnull public Account getAccount() - throws NoSuchAccountException + throws NoSuchAccountException { try { return new Account(mMbox.getAccount()); } - catch (com.zimbra.common.service.ServiceException serviceException) + catch (ServiceException serviceException) { throw ExceptionWrapper.wrap(serviceException); } @@ -332,7 +296,7 @@ public String getAccountId() public int getId() { - return (int) mMbox.getId(); + return mMbox.getId(); } public boolean hasListener(String listenerName) @@ -351,11 +315,11 @@ public void registerListener(@Nonnull Listener listener) { mMbox.addListener(listener.getStoreContext().toZimbra(Session.class)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { ZimbraLog.mailbox.warn("Error adding listener to mailbox " + - mMbox.getId() + ": " + - e.getMessage()); + mMbox.getId() + ": " + + e.getMessage()); } } @@ -364,11 +328,6 @@ public void unregisterListener(@Nonnull Listener listener) mMbox.removeListener(listener.getStoreContext().toZimbra(Session.class)); } - public void unregisterListener(@Nonnull MailboxSessionProxy session) - { - mMbox.removeListener(session.toZimbra(Session.class)); - } - private static int getMailboxSyncCutoff(@Nonnull com.zimbra.cs.mailbox.Mailbox mMbox) { return mMbox.getSyncCutoff(); @@ -382,30 +341,14 @@ public boolean isTombstoneValid(int sequence) @Nonnull public Item getItemById(@Nonnull OperationContext zContext, int id, byte type) - throws NoSuchItemException + throws NoSuchItemException { MailItem item; try { item = mMbox.getItemById(zContext.getOperationContext(), id, Item.convertType(type)); } - catch (com.zimbra.common.service.ServiceException serviceException) - { - throw ExceptionWrapper.wrap(serviceException); - } - return new Item(item); - } - - @Nonnull - public Item getItemByUuId(@Nonnull OperationContext zContext, String uuid, byte type, boolean fromDumpster) - throws NoSuchItemException - { - MailItem item; - try - { - item = mMbox.getItemByUuid(zContext.getOperationContext(), uuid, Item.convertType(type),fromDumpster); - } - catch (com.zimbra.common.service.ServiceException serviceException) + catch (ServiceException serviceException) { throw ExceptionWrapper.wrap(serviceException); } @@ -414,14 +357,14 @@ public Item getItemByUuId(@Nonnull OperationContext zContext, String uuid, byte @Nonnull public Item getItemByIdFromDumpster(@Nonnull OperationContext zContext, int id, byte type) - throws NoSuchItemException + throws NoSuchItemException { MailItem item; try { item = mMbox.getItemById(zContext.getOperationContext(), id, Item.convertType(type), true); } - catch (com.zimbra.common.service.ServiceException serviceException) + catch (ServiceException serviceException) { throw ExceptionWrapper.wrap(serviceException); } @@ -430,50 +373,14 @@ public Item getItemByIdFromDumpster(@Nonnull OperationContext zContext, int id, @Nonnull public Item getItemRevisionById(@Nonnull OperationContext zContext, int id, byte type, int revision) - throws NoSuchItemException + throws NoSuchItemException { MailItem item; try { item = mMbox.getItemRevision(zContext.getOperationContext(), id, Item.convertType(type), revision); } - catch (com.zimbra.common.service.ServiceException serviceException) - { - throw ExceptionWrapper.wrap(serviceException); - } - if (item == null) - { - throw new NoSuchItemException(id+"-"+revision); - } - return new Item(item); - } - - @Nullable private static Method sLoadRevisionsMethod = null; - - static - { - try - { - sLoadRevisionsMethod = com.zimbra.cs.mailbox.MailItem.class.getDeclaredMethod("loadRevisions"); - sLoadRevisionsMethod.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - @Nonnull - public Item getItemRevisionByIdFromDumpster(@Nonnull OperationContext zContext, int id, byte type, int revision) - throws NoSuchItemException - { - MailItem item; - try - { - item = mMbox.getItemRevision(zContext.getOperationContext(), id, Item.convertType(type), revision, true); - } - catch (com.zimbra.common.service.ServiceException serviceException) + catch (ServiceException serviceException) { throw ExceptionWrapper.wrap(serviceException); } @@ -520,15 +427,15 @@ public List getAllRevisions(@Nonnull OperationContext zContext, int id, by MailItem mailItem = item.toZimbra(MailItem.class); List revisions; - Object revisionsObject = sLoadRevisionsMethod.invoke(mailItem); + List revisionsObject = mailItem.loadRevisions(); if (revisionsObject == null) { revisions = Collections.singletonList(item); } else { - List zimbraRevisions = (List) revisionsObject; - revisions = new ArrayList(zimbraRevisions.size()); + List zimbraRevisions = revisionsObject; + revisions = new ArrayList<>(zimbraRevisions.size()); for (MailItem zimbraItem : zimbraRevisions) { revisions.add(new Item(zimbraItem)); @@ -547,7 +454,7 @@ public List getAllRevisions(@Nonnull OperationContext zContext, int id, by { List mailItems = mMbox.getAllRevisions(zContext.getOperationContext(), id, Item.convertType(type)); - List items = new ArrayList(mailItems.size()); + List items = new ArrayList<>(mailItems.size()); for (MailItem mailItem : mailItems) { items.add(new Item(mailItem)); @@ -556,19 +463,15 @@ public List getAllRevisions(@Nonnull OperationContext zContext, int id, by return items; } } - catch (com.zimbra.common.service.ServiceException serviceException) + catch (ServiceException serviceException) { throw ExceptionWrapper.wrap(serviceException); } - catch (IllegalAccessException | InvocationTargetException e) - { - throw new RuntimeException(e); - } } @Nonnull public Message getMessageById(@Nonnull OperationContext zContext, int id) - throws NoSuchMessageException + throws NoSuchMessageException { try { @@ -583,7 +486,7 @@ public Message getMessageById(@Nonnull OperationContext zContext, int id) @Nonnull public List getMessagesByConversation(@Nonnull OperationContext zContext, int id) - throws NoSuchConversationException + throws NoSuchConversationException { List list; try @@ -594,7 +497,7 @@ public List getMessagesByConversation(@Nonnull OperationContext zContex { throw ExceptionWrapper.wrap(exception); } - List newList = new ArrayList(list.size()); + List newList = new ArrayList<>(list.size()); for (com.zimbra.cs.mailbox.Message item : list) { @@ -604,58 +507,13 @@ public List getMessagesByConversation(@Nonnull OperationContext zContex return newList; } - public void setDate(@Nonnull OperationContext octxt, int itemId, byte type, long date) - { - try - { - mMbox.setDate(octxt.getOperationContext(), itemId, Item.convertType(type), date); - } - catch (com.zimbra.common.service.ServiceException serviceException) - { - throw ExceptionWrapper.wrap(serviceException); - } - } - - @Nonnull - public List getModifiedTags(@Nonnull OperationContext octxt, int lastSync) - { - List list; - try - { - list = mMbox.getModifiedTags(octxt.getOperationContext(), lastSync); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - List newList = new ArrayList(list.size()); - - for (MailItem item : list) - { - newList.add(new Tag(item)); - } - return newList; - } - - public List getModifiedItems(@Nonnull OperationContext zContext, int sequence) - { - try - { - return mMbox.getModifiedItems(zContext.getOperationContext(), sequence).getFirst(); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - public List listTombstones(int sequence) { try { return mMbox.getTombstones(sequence).getAllIds(); } - catch (com.zimbra.common.service.ServiceException serviceException) + catch (ServiceException serviceException) { throw ExceptionWrapper.wrap(serviceException); } @@ -663,14 +521,14 @@ public List listTombstones(int sequence) @Nonnull public Folder getFolderByName(@Nonnull OperationContext zContext, String name, int parentId) - throws NoSuchFolderException + throws NoSuchFolderException { MailItem folder; try { folder = mMbox.getFolderByName(zContext.getOperationContext(), parentId, name); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -680,14 +538,14 @@ public Folder getFolderByName(@Nonnull OperationContext zContext, String name, i @Nonnull public Folder getFolderByPath(@Nonnull OperationContext zContext, String path) - throws NoSuchFolderException + throws NoSuchFolderException { MailItem folder; try { folder = mMbox.getFolderByPath(zContext.getOperationContext(), path); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -697,18 +555,18 @@ public Folder getFolderByPath(@Nonnull OperationContext zContext, String path) @Nonnull public List getFolderList(@Nonnull OperationContext zContext) - throws NoSuchFolderException + throws NoSuchFolderException { List folderList = new ArrayList<>(0); try { for (com.zimbra.cs.mailbox.Folder folder : mMbox - .getFolderList(zContext.getOperationContext(), SortBy.NONE)) { + .getFolderList(zContext.getOperationContext(), SortBy.NONE)) { folderList.add(new Folder(folder)); } } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -716,73 +574,16 @@ public List getFolderList(@Nonnull OperationContext zContext) return folderList; } - @Nonnull - public Item getItemByPath(@Nonnull OperationContext zContext, String path) - throws NoSuchItemException - { - MailItem mailItem; - try - { - mailItem = mMbox.getItemByPath(zContext.getOperationContext(), path); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - return new Folder(mailItem); - } - - @Nonnull - public List getModifiedFolders(int sequence) - throws NoSuchFolderException - { - List folderList; - try - { - folderList = mMbox.getModifiedFolders(sequence); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - List newFolderList = new ArrayList(folderList.size()); - - for (com.zimbra.cs.mailbox.Folder folder : folderList) - { - newFolderList.add(new Folder(folder)); - } - - return newFolderList; - } - /* - public Folder getFolderById( int id ) - throws ServiceException - { - MailItem folder; - try - { - folder = mMbox.getFolderById(id); - } - catch(com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - return new Folder(folder); - } - */ - @Nonnull public Folder getFolderById(@Nonnull OperationContext zContext, int id) - throws NoSuchFolderException + throws NoSuchFolderException { MailItem folder; try { folder = mMbox.getFolderById(zContext.getOperationContext(), id); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -798,7 +599,7 @@ public Mountpoint getMountpointById(@Nonnull OperationContext octxt, int id) { mountpoint = mMbox.getMountpointById(octxt.getOperationContext(), id); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -808,13 +609,13 @@ public Mountpoint getMountpointById(@Nonnull OperationContext octxt, int id) @Nonnull public CalendarItem getCalendarItemById(@Nonnull OperationContext octxt, int id) - throws NoSuchCalendarException + throws NoSuchCalendarException { try { return new CalendarItem(mMbox.getCalendarItemById(octxt.getOperationContext(), id)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -822,14 +623,14 @@ public CalendarItem getCalendarItemById(@Nonnull OperationContext octxt, int id) @Nonnull public CalendarItem getCalendarItemByUid(@Nonnull OperationContext octxt, String uid) - throws NoSuchCalendarException + throws NoSuchCalendarException { MailItem mailItem; try { mailItem = mMbox.getCalendarItemByUid(octxt.getOperationContext(), uid); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -842,32 +643,32 @@ public CalendarItem getCalendarItemByUid(@Nonnull OperationContext octxt, String return new CalendarItem(mailItem); } - @Nonnull - public FreeBusy getFreeBusy(@Nonnull OperationContext octxt, long start, long end) - throws NoSuchItemException + @Nonnull + public FreeBusy getFreeBusy(@Nonnull OperationContext octxt, long start, long end) + throws NoSuchItemException + { + com.zimbra.cs.fb.FreeBusy freeBusy; + try { - com.zimbra.cs.fb.FreeBusy freeBusy; - try - { - freeBusy = mMbox.getFreeBusy(octxt.getOperationContext(),start,end,FreeBusyQuery.CALENDAR_FOLDER_ALL); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - if (freeBusy == null) - { - throw new NoSuchFreeBusyException(start, end); - } + freeBusy = mMbox.getFreeBusy(octxt.getOperationContext(),start,end,FreeBusyQuery.CALENDAR_FOLDER_ALL); + } + catch (ServiceException e) + { + throw ExceptionWrapper.wrap(e); + } - return new FreeBusy(freeBusy); + if (freeBusy == null) + { + throw new NoSuchFreeBusyException(start, end); } + return new FreeBusy(freeBusy); + } + public void copyCalendarReplyInfo( - @Nonnull CalendarItem fromCalendarItem, - CalendarItem toCalendarItem, - @Nonnull OperationContext zContext + @Nonnull CalendarItem fromCalendarItem, + CalendarItem toCalendarItem, + @Nonnull OperationContext zContext ) { synchronized (mMbox) @@ -885,78 +686,70 @@ public void copyCalendarReplyInfo( } public void rename(@Nonnull OperationContext zContext, int id, byte type, String name, int folderId) - throws ZimbraException + throws ZimbraException { try { mMbox.rename(zContext.getOperationContext(), id, Item.convertType(type), name, folderId); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } - public void renameMailbox(OperationContext operationContext, String oldName, String newName) { - try { - mMbox.renameMailbox(operationContext.getOperationContext(), oldName, newName); - } catch (com.zimbra.common.service.ServiceException e) { - throw ExceptionWrapper.wrap(e); - } - } - public void delete(@Nonnull OperationContext octxt, int itemId, byte type) - throws ZimbraException + throws ZimbraException { try { mMbox.delete(octxt.getOperationContext(), itemId, Item.convertType(type)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void delete(@Nonnull OperationContext octxt, int[] itemIds, byte type) - throws ZimbraException + throws ZimbraException { try { mMbox.delete(octxt.getOperationContext(), itemIds, Item.convertType(type), null); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void setPermissions(@Nonnull OperationContext zContext, int folderId, @Nonnull Acl acl) - throws ZimbraException + throws ZimbraException { try { mMbox.setPermissions(zContext.getOperationContext(), folderId, acl.toZimbra(ACL.class)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void setColor(@Nonnull OperationContext octxt, int[] itemIds, byte type, @Nonnull Item.Color color) - throws ZimbraException + throws ZimbraException { try { mMbox.setColor( - octxt.getOperationContext(), - itemIds, - Item.convertType(type), - color.toZimbra(com.zimbra.common.mailbox.Color.class) + octxt.getOperationContext(), + itemIds, + Item.convertType(type), + color.toZimbra(com.zimbra.common.mailbox.Color.class) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -964,12 +757,12 @@ public void setColor(@Nonnull OperationContext octxt, int[] itemIds, byte type, @Nonnull public CalendarItem setCalendarItem( - @Nonnull OperationContext octxt, int folderId, int flags, String tags[], - @Nonnull CalendarItemData defaultInv, - @Nonnull List exceptions, - List replies, long nextAlarm + @Nonnull OperationContext octxt, int folderId, int flags, String tags[], + @Nonnull CalendarItemData defaultInv, + @Nonnull List exceptions, + List replies, long nextAlarm ) - throws ZimbraException + throws ZimbraException { com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData[] zimbraExceptions = null; if( exceptions.size() > 0 ) @@ -990,8 +783,8 @@ public CalendarItem setCalendarItem( calendarItemData.invite.setMethod("PUBLISH"); com.zimbra.cs.mailbox.CalendarItem calendarItem = calendarItemData.invite.getCalendarItem(); String cid = String.format("Message Id: %s from account id %s", - calendarItem.getId(), - calendarItem.getAccount().getId() + calendarItem.getId(), + calendarItem.getAccount().getId() ); ZimbraLog.extensions.warn(String.format("Setting metadata method to 'PUBLISH', '%s' is not supported for calendar item %s", oldMethod, cid)); } @@ -1003,20 +796,20 @@ public CalendarItem setCalendarItem( } CalendarItem result = new CalendarItem( - mMbox.setCalendarItem( - octxt.getOperationContext(), - folderId, - flags, - tags, - calendarItemData, - zimbraExceptions, - newReplies, - nextAlarm - ) + mMbox.setCalendarItem( + octxt.getOperationContext(), + folderId, + flags, + tags, + calendarItemData, + zimbraExceptions, + newReplies, + nextAlarm + ) ); return result; } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1025,7 +818,7 @@ public CalendarItem setCalendarItem( public @Nullable Metadata getConfig(@Nonnull OperationContext octxt, String section) - throws ZimbraException + throws ZimbraException { try { @@ -1036,73 +829,43 @@ Metadata getConfig(@Nonnull OperationContext octxt, String section) } return new Metadata(metadata); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void setConfig(@Nonnull OperationContext octxt, String section, @Nonnull Metadata config) - throws ZimbraException - { - try - { - mMbox.setConfig( - octxt.getOperationContext(), - section, - config.toZimbra(com.zimbra.cs.mailbox.Metadata.class)); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public void removeConfig(@Nonnull OperationContext octxt, String section) - throws ZimbraException + throws ZimbraException { try { mMbox.setConfig( - octxt.getOperationContext(), - section, - null - ); + octxt.getOperationContext(), + section, + config.toZimbra(com.zimbra.cs.mailbox.Metadata.class)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void alterTag(@Nonnull OperationContext octxt, int itemId, byte type, int tagId, boolean addTag) - throws ZimbraException + throws ZimbraException { try { mMbox.alterTag(octxt.getOperationContext(), itemId, Item.convertType(type), Flag.of(tagId), addTag, null); } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public void alterTag(@Nonnull OperationContext octxt, int itemId, byte type, String tagName, boolean addTag) - throws ZimbraException - { - try - { - mMbox.alterTag(octxt.getOperationContext(), itemId, Item.convertType(type), tagName, addTag, null); - } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void setTags(@Nonnull OperationContext octxt, int itemId, byte type, @Nullable Collection tags) - throws ZimbraException + throws ZimbraException { String[] tagsArray; if (tags == null) @@ -1119,47 +882,47 @@ public void setTags(@Nonnull OperationContext octxt, int itemId, byte type, @Nul { item = mMbox.getItemById(octxt.getOperationContext(), itemId, Item.convertType(Item.TYPE_UNKNOWN)); mMbox.setTags( - octxt.getOperationContext(), - itemId, - Item.convertType(type), - item.getFlagBitmask(), - tagsArray + octxt.getOperationContext(), + itemId, + Item.convertType(type), + item.getFlagBitmask(), + tagsArray ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void setFlags(@Nonnull OperationContext octxt, int itemId, byte type, int flags) - throws ZimbraException + throws ZimbraException { try { MailItem item = mMbox.getItemById(octxt.getOperationContext(), itemId, Item.convertType(Item.TYPE_UNKNOWN)); mMbox.setTags(octxt.getOperationContext(), itemId, Item.convertType(type), flags, - item.getTags() + item.getTags() ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void modifyContact(@Nonnull OperationContext octxt, int contactId, @Nonnull ParsedContact pc) - throws ZimbraException + throws ZimbraException { try { mMbox.modifyContact( - octxt.getOperationContext(), - contactId, - pc.toZimbra(com.zimbra.cs.mime.ParsedContact.class) + octxt.getOperationContext(), + contactId, + pc.toZimbra(com.zimbra.cs.mime.ParsedContact.class) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1167,12 +930,12 @@ public void modifyContact(@Nonnull OperationContext octxt, int contactId, @Nonnu @Nullable public ZimbraItemId sendMimeMessage( - @Nonnull OperationContext octxt, Boolean saveToSent, MimeMessage mm, - List uploads, - @Nullable ZimbraItemId origMsgId, String replyType, - boolean replyToSender + @Nonnull OperationContext octxt, Boolean saveToSent, MimeMessage mm, + List uploads, + @Nullable ZimbraItemId origMsgId, String replyType, + boolean replyToSender ) - throws ZimbraException + throws ZimbraException { ItemId itemId = null; @@ -1186,9 +949,9 @@ public ZimbraItemId sendMimeMessage( try { newItemId = mMbox.getMailSender().sendMimeMessage( - octxt.getOperationContext(), mMbox, saveToSent, mm, - uploads, itemId, replyType, - null, replyToSender + octxt.getOperationContext(), mMbox, saveToSent, mm, + uploads, itemId, replyType, + null, replyToSender ); if( newItemId == null ) { @@ -1196,20 +959,20 @@ public ZimbraItemId sendMimeMessage( } return new ZimbraItemId(newItemId.getAccountId(), newItemId.getId()); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public boolean attachmentsIndexingEnabled() - throws ZimbraException + throws ZimbraException { try { return mMbox.attachmentsIndexingEnabled(); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1226,71 +989,28 @@ public void move(@Nonnull OperationContext octxt, int itemId, byte type, int tar } mMbox.move(octxt.getOperationContext(), itemId, Item.convertType(type), targetId); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } - public void move(@Nonnull OperationContext octxt, int[] itemIds, byte type, int targetId) throws ZimbraException + public int move(@Nonnull Account dstAccount,@Nonnull OperationContext octxt, int itemId, byte type, int targetId) + throws ZimbraException { try { - mMbox.move(octxt.getOperationContext(), itemIds, Item.convertType(type), targetId, null); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public List copy(@Nonnull OperationContext octxt, int[] itemIds, byte type, int targetId) throws ZimbraException - { - try - { - List copiedItems = mMbox.copy(octxt.getOperationContext(), itemIds, Item.convertType(type), targetId); - List result = new ArrayList<>(copiedItems.size()); - for( MailItem mailItem : copiedItems ) { - result.add(new Item(mailItem)); - } - return result; - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public void createFolderPath(@Nonnull OperationContext octxt, String path) throws ZimbraException - { - try - { - mMbox.createFolderForMsgs(octxt.getOperationContext(), path); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - - - public int move(@Nonnull Account dstAccount,@Nonnull OperationContext octxt, int itemId, byte type, int targetId) - throws ZimbraException - { - try - { - com.zimbra.cs.service.util.ItemId zimbraItemId = new com.zimbra.cs.service.util.ItemId( + ItemId zimbraItemId = new ItemId( dstAccount.getId(), targetId ); ItemActionHelper op = ItemActionHelper.MOVE(octxt.getOperationContext(), - mMbox, - SoapProtocol.Soap12, - Arrays.asList(itemId), - Item.convertType(type), - null, - zimbraItemId); + mMbox, + SoapProtocol.Soap12, + Arrays.asList(itemId), + Item.convertType(type), + null, + zimbraItemId); List createdIds; createdIds = op.getResult().getSuccessIds(); if (createdIds == null) @@ -1301,80 +1021,48 @@ public int move(@Nonnull Account dstAccount,@Nonnull OperationContext octxt, int { throw new NoSuchItemException(Integer.toString(itemId)); } - com.zimbra.cs.service.util.ItemId newZimbraItemId = new com.zimbra.cs.service.util.ItemId(createdIds.get(0),(String)null); + ItemId newZimbraItemId = new ItemId(createdIds.get(0),(String)null); return newZimbraItemId.getId(); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public List getCalendarItemsForRange( - @Nonnull OperationContext octxt, byte type, long start, - long end, int folderId, int[] excludeFolders + @Nonnull OperationContext octxt, byte type, long start, + long end, int folderId, int[] excludeFolders ) - throws ZimbraException + throws ZimbraException { try { List zimbraCalendarItems = mMbox.getCalendarItemsForRange( - octxt.getOperationContext(), - Item.convertType(type), - start, - end, - folderId, - excludeFolders + octxt.getOperationContext(), + Item.convertType(type), + start, + end, + folderId, + excludeFolders ); return ZimbraListWrapper.wrapCalendarItems(zimbraCalendarItems); } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public List getItemListByDates( - @Nonnull OperationContext octxt, byte type, long start, - long end, int folderId, boolean descending - ) - throws ZimbraException - { - List itemIds; - - try - { - DbMailItem.QueryParams options = new DbMailItem.QueryParams(); - options.setFolderIds(Collections.singletonList(folderId)); - options.setIncludedTypes(Collections.singletonList(Item.convertType(type))); - options.setDateAfter((int) (start / 1000L)); - options.setDateBefore((int) (end / 1000L)); - if (descending) - { - options.setOrderBy(Collections.singletonList("date DESC")); - } - else - { - options.setOrderBy(Collections.singletonList("date ASC")); - } - itemIds = mMbox.getItemIdList(octxt.getOperationContext(), options); - return itemIds; - } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public List listItemIds(@Nonnull OperationContext octxt, byte type, int folderId) - throws NoSuchItemException + throws NoSuchItemException { try { return mMbox.listItemIds(octxt.getOperationContext(), Item.convertType(type), folderId); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1382,17 +1070,17 @@ public List listItemIds(@Nonnull OperationContext octxt, byte type, int @Nonnull public Iterator>> getItemIds(@Nonnull OperationContext octxt, int folderId) - throws ZimbraException + throws ZimbraException { try { - Map> map = new HashMap>(); - Iterator>> iterator - = mMbox.getItemIds(octxt.getOperationContext(), folderId).iterator(); + Map> map = new HashMap<>(); + Iterator>> iterator + = mMbox.getItemIds(octxt.getOperationContext(), folderId).iterator(); while (iterator.hasNext()) { - Map.Entry> entry = iterator.next(); - List list = new ArrayList(); + Map.Entry> entry = iterator.next(); + List list = new ArrayList<>(); for (TypedIdList.ItemInfo item : entry.getValue()) { list.add(item.getId()); @@ -1401,7 +1089,7 @@ public Iterator>> getItemIds(@Nonnull OperationCon } return map.entrySet().iterator(); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1413,7 +1101,7 @@ public boolean canRead(OperationContext octxt, int itemId) try { - rights = mMbox.getEffectivePermissions(octxt.getOperationContext(), itemId, com.zimbra.cs.mailbox.MailItem.Type.UNKNOWN); + rights = mMbox.getEffectivePermissions(octxt.getOperationContext(), itemId, Type.UNKNOWN); } catch (ServiceException e) { @@ -1429,7 +1117,7 @@ public boolean canWrite(OperationContext octxt, int itemId) try { - rights = mMbox.getEffectivePermissions(octxt.getOperationContext(), itemId, com.zimbra.cs.mailbox.MailItem.Type.UNKNOWN); + rights = mMbox.getEffectivePermissions(octxt.getOperationContext(), itemId, Type.UNKNOWN); } catch (ServiceException e) { @@ -1440,11 +1128,11 @@ public boolean canWrite(OperationContext octxt, int itemId) } public void modifyPartStat( - @Nonnull OperationContext octxt, int calItemId, - @Nullable RecurrenceId recurId, String cnStr, - String addressStr, String cutypeStr, - String roleStr, String partStatStr, - Boolean rsvp, int seqNo, long dtStamp + @Nonnull OperationContext octxt, int calItemId, + @Nullable RecurrenceId recurId, String cnStr, + String addressStr, String cutypeStr, + String roleStr, String partStatStr, + Boolean rsvp, int seqNo, long dtStamp ) throws ZimbraException { @@ -1469,7 +1157,7 @@ public void modifyPartStat( seqNo, dtStamp); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1477,14 +1165,14 @@ public void modifyPartStat( @Nonnull public Tag getTagById(@Nonnull OperationContext octxt, int itemId) - throws NoSuchItemException + throws NoSuchItemException { MailItem tag; try { tag = mMbox.getTagById(octxt.getOperationContext(), itemId); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1493,7 +1181,7 @@ public Tag getTagById(@Nonnull OperationContext octxt, int itemId) @Nullable public Tag getTagByName(@Nonnull OperationContext octxt, String name) - throws NoSuchItemException + throws NoSuchItemException { try { @@ -1504,58 +1192,52 @@ public Tag getTagByName(@Nonnull OperationContext octxt, String name) } return new Tag(tagByName); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void setCustomData(@Nonnull OperationContext octxt, int itemId, byte type, @Nonnull Item.CustomMetadata custom) - throws ZimbraException + throws ZimbraException { try { mMbox.setCustomData( - octxt.getOperationContext(), - itemId, - Item.convertType(type), - custom.toZimbra(MailItem.CustomMetadata.class) + octxt.getOperationContext(), + itemId, + Item.convertType(type), + custom.toZimbra(MailItem.CustomMetadata.class) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } - @Nonnull - public ZimbraItemId nextItemId() - { - return new ZimbraItemId(mMbox.getAccountId(), 0); - } - @Nonnull public OperationContext newOperationContext() - throws ZimbraException + throws ZimbraException { try { return new OperationContext(new com.zimbra.cs.mailbox.OperationContext(mMbox)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void beginTrackingSync() - throws ZimbraException + throws ZimbraException { try { mMbox.beginTrackingSync(); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1566,11 +1248,6 @@ public int getLastChangeID() return mMbox.getLastChangeID(); } - public int getLastItemId() - { - return mMbox.getLastItemId(); - } - public void clearItemCache() throws ZimbraException { mMbox.purge(Item.convertType(Item.TYPE_UNKNOWN)); @@ -1583,32 +1260,32 @@ public void purgeCache() public void clearCache(byte type) throws ZimbraException { - mMbox.purge(Item.convertType(type)); + mMbox.purge(Item.convertType(type)); } @Nonnull public QueryResults search( - @Nonnull OperationContext octxt, - String queryString, - @Nonnull byte[] types, - @Nonnull SortedBy sortBy, - int chunkSize + @Nonnull OperationContext octxt, + String queryString, + @Nonnull byte[] types, + @Nonnull SortedBy sortBy, + int chunkSize ) - throws ZimbraException + throws ZimbraException { return search(octxt, queryString, types, sortBy, chunkSize, 0, false, false); } @Nonnull public QueryResults search( - @Nonnull OperationContext octxt, - String queryString, - @Nonnull byte[] types, - @Nonnull SortedBy sortBy, - int chunkSize, - int offset, - boolean onlyIds + @Nonnull OperationContext octxt, + String queryString, + @Nonnull byte[] types, + @Nonnull SortedBy sortBy, + int chunkSize, + int offset, + boolean onlyIds ) throws ZimbraException { @@ -1616,41 +1293,41 @@ public QueryResults search( } public QueryResults search( - OperationContext operationContext, - org.openzal.zal.SearchParams searchParams + OperationContext operationContext, + org.openzal.zal.SearchParams searchParams ) { ZimbraQueryResults result; try { result = mMbox.index.search( - SoapProtocol.Soap12, - operationContext.getOperationContext(), - searchParams.toZimbra(SearchParams.class) + SoapProtocol.Soap12, + operationContext.getOperationContext(), + searchParams.toZimbra(SearchParams.class) ); } catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } return new QueryResults( - result + result ); } @Nonnull public QueryResults search( - @Nonnull OperationContext octxt, - String queryString, - @Nonnull byte[] types, - @Nonnull SortedBy sortBy, - int chunkSize, - int offset, - boolean onlyIds, - boolean inDumpster + @Nonnull OperationContext octxt, + String queryString, + @Nonnull byte[] types, + @Nonnull SortedBy sortBy, + int chunkSize, + int offset, + boolean onlyIds, + boolean inDumpster ) - throws ZimbraException + throws ZimbraException { try { - Set typeList = new HashSet(types.length); + Set typeList = new HashSet(types.length); for (byte type : types) { typeList.add(Item.convertType(type)); @@ -1658,7 +1335,7 @@ public QueryResults search( SearchParams.Fetch fetchMode = onlyIds ? SearchParams.Fetch.IDS : SearchParams.Fetch.NORMAL; - com.zimbra.cs.index.SearchParams params = new com.zimbra.cs.index.SearchParams(); + SearchParams params = new SearchParams(); params.setQueryString(queryString); params.setTimeZone(null); params.setLocale(null); @@ -1671,16 +1348,16 @@ public QueryResults search( params.setOffset(offset); ZimbraQueryResults result = mMbox.index.search( - SoapProtocol.Soap12, - octxt.getOperationContext(), - params + SoapProtocol.Soap12, + octxt.getOperationContext(), + params ); if( offset >= 1 ) result.skipToHit(offset-1); return new QueryResults( - result + result ); } catch (Exception e) @@ -1691,9 +1368,9 @@ public QueryResults search( @Nonnull public List getItemList(byte type, @Nonnull OperationContext zContext) - throws ZimbraException + throws ZimbraException { - List result = new LinkedList(); + List result = new LinkedList<>(); beginTransaction("ZxGetItemList", zContext.getOperationContext()); try @@ -1767,27 +1444,27 @@ else if (type == Item.TYPE_FLAG) @Nonnull public Folder createFolder( - @Nonnull OperationContext octxt, String name, int parentId, - byte attrs, byte defaultView, int flags, - @Nonnull Item.Color color, String url + @Nonnull OperationContext octxt, String name, int parentId, + byte attrs, byte defaultView, int flags, + @Nonnull Item.Color color, String url ) - throws ZimbraException + throws ZimbraException { MailItem folder; try { folder = mMbox.createFolder( - octxt.getOperationContext(), - name, - parentId, - attrs, - Item.convertType(defaultView), - flags, - color.toZimbra(com.zimbra.common.mailbox.Color.class), - url + octxt.getOperationContext(), + name, + parentId, + attrs, + Item.convertType(defaultView), + flags, + color.toZimbra(com.zimbra.common.mailbox.Color.class), + url ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1797,27 +1474,27 @@ public Folder createFolder( @Nonnull public Folder createFolder( - OperationContext operationContext, - String path + OperationContext operationContext, + String path ) { MailItem folder; try { FolderOptions fopts = new FolderOptions(); folder = mMbox.createFolder(operationContext.getOperationContext(), path, fopts); - } catch (com.zimbra.common.service.ServiceException e) { + } catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } return new Folder(folder); } public void setFolderRetentionPolicy(@Nonnull OperationContext octxt, int folderId, RetentionPolicy retentionPolicy) - throws ZimbraException { + throws ZimbraException { try { mMbox.setRetentionPolicy( - octxt.getOperationContext(), - folderId, - Type.FOLDER, - retentionPolicy.toZimbra(com.zimbra.soap.mail.type.RetentionPolicy.class) + octxt.getOperationContext(), + folderId, + Type.FOLDER, + retentionPolicy.toZimbra(com.zimbra.soap.mail.type.RetentionPolicy.class) ); } catch (ServiceException e) { throw ExceptionWrapper.wrap(e); @@ -1826,27 +1503,27 @@ public void setFolderRetentionPolicy(@Nonnull OperationContext octxt, int folder @Nonnull public SearchFolder createSearchFolder( - @Nonnull OperationContext octxt, int folderId, String name, - String query, String types, String sort, - int flags, @Nonnull Item.Color color + @Nonnull OperationContext octxt, int folderId, String name, + String query, String types, String sort, + int flags, @Nonnull Item.Color color ) - throws ZimbraException + throws ZimbraException { MailItem item; try { item = mMbox.createSearchFolder( - octxt.getOperationContext(), - folderId, - name, - query, - types, - sort, - flags, - color.toZimbra(com.zimbra.common.mailbox.Color.class) + octxt.getOperationContext(), + folderId, + name, + query, + types, + sort, + flags, + color.toZimbra(com.zimbra.common.mailbox.Color.class) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1854,47 +1531,20 @@ public SearchFolder createSearchFolder( return new SearchFolder(item); } - @Nonnull - public SearchFolder getSearchFolderById(@Nonnull OperationContext zContext, int id) throws NoSuchFolderException { - MailItem folder; - - try - { - folder = mMbox.getSearchFolderById(zContext.getOperationContext(), id); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - return new SearchFolder(folder); - } - - public void modifySearchFolder(OperationContext zContext, int id, String query, String types, String sort) { - try - { - mMbox.modifySearchFolder(zContext.getOperationContext(), id, query, types, sort); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - @Nonnull public Tag createTag(@Nonnull OperationContext octxt, String name, @Nonnull Item.Color color) - throws ZimbraException + throws ZimbraException { MailItem tag; try { tag = mMbox.createTag( - octxt.getOperationContext(), - name, - color.toZimbra(com.zimbra.common.mailbox.Color.class) + octxt.getOperationContext(), + name, + color.toZimbra(com.zimbra.common.mailbox.Color.class) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1904,12 +1554,12 @@ public Tag createTag(@Nonnull OperationContext octxt, String name, @Nonnull Item @Nonnull public Message addMessage( - @Nonnull OperationContext octxt, InputStream in, int sizeHint, Long receivedDate, - int folderId, boolean noIcal, - int flags, Collection tags, int conversationId, String rcptEmail, - @Nullable Item.CustomMetadata customData + @Nonnull OperationContext octxt, InputStream in, int sizeHint, Long receivedDate, + int folderId, boolean noIcal, + int flags, Collection tags, int conversationId, String rcptEmail, + @Nullable Item.CustomMetadata customData ) - throws IOException, ZimbraException + throws IOException, ZimbraException { DeliveryOptions opts = new DeliveryOptions(); opts.setFolderId(folderId); @@ -1927,14 +1577,14 @@ public Message addMessage( try { message = mMbox.addMessage(octxt.getOperationContext(), - in, - sizeHint, - receivedDate, - opts, - null + in, + sizeHint, + receivedDate, + opts, + null ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1944,11 +1594,11 @@ public Message addMessage( @Nonnull public Message simpleAddMessage( - @Nonnull OperationContext octxt, - InputStream in, - int folderId + @Nonnull OperationContext octxt, + InputStream in, + int folderId ) - throws IOException, ZimbraException + throws IOException, ZimbraException { MailItem message; try @@ -1957,15 +1607,15 @@ public Message simpleAddMessage( opts.setFolderId(folderId); opts.setDraftInfo(null); message = mMbox.addMessage( - octxt.getOperationContext(), - in, - 0L, - null, - opts, - null + octxt.getOperationContext(), + in, + 0L, + null, + opts, + null ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -1975,13 +1625,13 @@ public Message simpleAddMessage( @Nonnull public Message saveDraft(@Nonnull OperationContext octxt,@Nonnull ParsedMessage parsedMessage, int id) - throws IOException, ZimbraException + throws IOException, ZimbraException { try { return new Message(mMbox.saveDraft(octxt.getOperationContext(), parsedMessage.toZimbra(com.zimbra.cs.mime.ParsedMessage.class), id)); } - catch( com.zimbra.common.service.ServiceException e ) + catch( ServiceException e ) { throw ExceptionWrapper.wrap(e); } @@ -2012,7 +1662,7 @@ public List getContacts(OperationContext octxt, int folderId) contacts.add(new Contact(contact)); } } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2023,24 +1673,24 @@ public List getContacts(OperationContext octxt, int folderId) @Nonnull public Contact createContact(OperationContext octxt, ParsedContact pc, int folderId) { - return createContact(octxt, pc, folderId, Collections.emptyList()); + return createContact(octxt, pc, folderId, Collections.emptyList()); } @Nonnull public Contact createContact(@Nonnull OperationContext octxt, @Nonnull ParsedContact pc, int folderId, @Nonnull Collection tags) - throws ZimbraException + throws ZimbraException { MailItem contact; try { contact = mMbox.createContact( - octxt.getOperationContext(), - pc.toZimbra(com.zimbra.cs.mime.ParsedContact.class), - folderId, - tags.toArray(new String[tags.size()]) + octxt.getOperationContext(), + pc.toZimbra(com.zimbra.cs.mime.ParsedContact.class), + folderId, + tags.toArray(new String[tags.size()]) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2048,13 +1698,13 @@ public Contact createContact(@Nonnull OperationContext octxt, @Nonnull ParsedCon return new Contact(contact); } public int addInvite( - @Nonnull OperationContext octxt, @Nonnull Invite inv, - int folderId, @Nullable ParsedMessage pm, - boolean preserveExistingAlarms, - boolean discardExistingInvites, - boolean addRevision + @Nonnull OperationContext octxt, @Nonnull Invite inv, + int folderId, @Nullable ParsedMessage pm, + boolean preserveExistingAlarms, + boolean discardExistingInvites, + boolean addRevision ) - throws ZimbraException + throws ZimbraException { try { @@ -2064,22 +1714,22 @@ public int addInvite( parsedMessage = pm.toZimbra(com.zimbra.cs.mime.ParsedMessage.class); } return mMbox.addInvite( - octxt.getOperationContext(), - inv.toZimbra(com.zimbra.cs.mailbox.calendar.Invite.class), - folderId, parsedMessage, - preserveExistingAlarms, - discardExistingInvites, - addRevision + octxt.getOperationContext(), + inv.toZimbra(com.zimbra.cs.mailbox.calendar.Invite.class), + folderId, parsedMessage, + preserveExistingAlarms, + discardExistingInvites, + addRevision ).calItemId; } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } } public void addInvite(@Nonnull OperationContext octxt, @Nonnull Invite inv, int folderId) - throws ZimbraException + throws ZimbraException { try { @@ -2094,7 +1744,7 @@ public void addInvite(@Nonnull OperationContext octxt, @Nonnull Invite inv, int true ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2116,7 +1766,7 @@ public void addInvite(@Nonnull OperationContext octxt, @Nonnull Invite inv, int true ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2124,29 +1774,29 @@ public void addInvite(@Nonnull OperationContext octxt, @Nonnull Invite inv, int @Nonnull public Mountpoint createMountpoint( - @Nonnull OperationContext octxt, int folderId, - String name, String ownerId, - int remoteId, String remoteUuid, - byte view, int flags, - @Nonnull Item.Color color + @Nonnull OperationContext octxt, int folderId, + String name, String ownerId, + int remoteId, String remoteUuid, + byte view, int flags, + @Nonnull Item.Color color ) - throws ZimbraException + throws ZimbraException { MailItem mountPoint; try { mountPoint = mMbox.createMountpoint( - octxt.getOperationContext(), folderId, - name, ownerId, - remoteId, - remoteUuid, - Item.convertType(view), - flags, - color.toZimbra(com.zimbra.common.mailbox.Color.class), - false + octxt.getOperationContext(), folderId, + name, ownerId, + remoteId, + remoteUuid, + Item.convertType(view), + flags, + color.toZimbra(com.zimbra.common.mailbox.Color.class), + false ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2154,115 +1804,17 @@ public Mountpoint createMountpoint( return new Mountpoint(mountPoint); } - - @Nonnull - public Chat createChat( - @Nonnull OperationContext octxt, - @Nonnull ParsedMessage pm, - int folderId, int flags, - @Nonnull Tags tags - ) - throws ZimbraException, IOException - { - MailItem chat; - try - { - chat = mMbox.createChat( - octxt.getOperationContext(), - pm.toZimbra(com.zimbra.cs.mime.ParsedMessage.class), - folderId, - flags, - tags.getTags() - ); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - return new Chat(chat); - } - - @Nonnull - public Chat createChat( - @Nonnull OperationContext octxt, - @Nonnull ParsedMessage pm, - int folderId, int flags - ) - throws ZimbraException, IOException - { - MailItem chat; - try - { - chat = mMbox.createChat( - octxt.getOperationContext(), - pm.toZimbra(com.zimbra.cs.mime.ParsedMessage.class), - folderId, - flags, - null); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - return new Chat(chat); - } - - @Nullable private static Method sEndTransactionMethod = null; - - static - { - try - { - Class partypes[] = new Class[1]; - partypes[0] = boolean.class; - - sEndTransactionMethod = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredMethod("endTransaction", partypes); - sEndTransactionMethod.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - @Nullable private static Method sBeginTransactionMethod = null; - - static - { - try - { - Class partypes[] = new Class[2]; - partypes[0] = String.class; - partypes[1] = com.zimbra.cs.mailbox.OperationContext.class; - - sBeginTransactionMethod = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredMethod("beginTransaction", partypes); - sBeginTransactionMethod.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public void beginTransaction(String name, @Nonnull OperationContext context) { beginTransaction(name, context.getOperationContext()); } - private final void beginTransaction(String name, com.zimbra.cs.mailbox.OperationContext zContext) - throws ZimbraException + private void beginTransaction(String name, com.zimbra.cs.mailbox.OperationContext zContext) + throws ZimbraException { try { - Object parameters[] = new Object[2]; - parameters[0] = name; - parameters[1] = zContext; - - sBeginTransactionMethod.invoke(mMbox, parameters); + mMbox.beginTransaction(name, zContext); } catch (Exception ex) { @@ -2271,14 +1823,11 @@ private final void beginTransaction(String name, com.zimbra.cs.mailbox.Operation } public final void endTransaction(boolean success) - throws ZimbraException + throws ZimbraException { - Object parameters[] = new Object[1]; - parameters[0] = success; - try { - sEndTransactionMethod.invoke(mMbox, parameters); + mMbox.endTransaction(success); } catch (Exception ex) { @@ -2286,38 +1835,16 @@ public final void endTransaction(boolean success) } } - private static Method sRawGetItem; - - static - { - try - { - Class partypes[] = new Class[1]; - partypes[0] = MailItem.UnderlyingData.class; - - sRawGetItem = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredMethod("getItem", partypes); - sRawGetItem.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - /* * Warning: unsynchronized private access to mailbox */ @Nullable - private final Item rawGetItem(@Nonnull Item.UnderlyingData data) - throws InternalServerException + private Item rawGetItem(@Nonnull Item.UnderlyingData data) + throws InternalServerException { - Object parameters[] = new Object[1]; - parameters[0] = data.toZimbra(MailItem.UnderlyingData.class); - try { - MailItem item = (MailItem) sRawGetItem.invoke(mMbox, parameters); + MailItem item = mMbox.getItem(data.toZimbra(MailItem.UnderlyingData.class)); if(item != null) { return new Item(item); @@ -2333,46 +1860,21 @@ private final Item rawGetItem(@Nonnull Item.UnderlyingData data) } } - private static Method sGetAllFlags; - - static - { - try - { - Class partypes[] = new Class[1]; - partypes[0] = com.zimbra.cs.mailbox.Mailbox.class; - - sGetAllFlags = com.zimbra.cs.mailbox.Flag.class.getDeclaredMethod("allOf", partypes); - sGetAllFlags.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - /* * Warning: unsynchronized private access to mailbox */ @Nullable - private final List getAllFlags() - throws ZimbraException + private List getAllFlags() + throws ZimbraException { - Object parameters[] = new Object[1]; - parameters[0] = mMbox; - - try - { - return (List) sGetAllFlags.invoke(null, parameters); - } - catch (Throwable ex) - { + try { + return com.zimbra.cs.mailbox.Flag.allOf(mMbox); + } catch (ServiceException | RuntimeException e) { return null; } } - public final static boolean ACLIsEmpty(@Nullable Acl acl) + public static boolean ACLIsEmpty(@Nullable Acl acl) { if (acl == null) { @@ -2381,109 +1883,27 @@ public final static boolean ACLIsEmpty(@Nullable Acl acl) return acl.isEmpty(); } - private static Field sTagCache; - - static - { - try - { - sTagCache = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredField("mTagCache"); - sTagCache.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - /* * Warning: unsynchronized private access to mailbox */ @Nullable - private final Map getTagCache() - { - try - { - Map tagsMap; - tagsMap = (Map) sTagCache.get(mMbox); - return tagsMap; - } - catch (Throwable ex) - { - return null; - } - } - - private static Field sFolderCache; - - static + private Map getTagCache() { - try - { - sFolderCache = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredField("mFolderCache"); - sFolderCache.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - private static Field sFolderCacheMap; - - static - { - try - { - Class cls = null; - Class subClasses[] = com.zimbra.cs.mailbox.Mailbox.class.getDeclaredClasses(); - - for (int n = 0; n < subClasses.length; ++n) - { - if (subClasses[n].getName().equals("com.zimbra.cs.mailbox.Mailbox$FolderCache")) - { - cls = subClasses[n]; - break; - } - } - if (cls == null) - { - ZimbraLog.extensions.fatal( - "ZAL Reflection Initialization Exception: " + - "com.zimbra.cs.mailbox.Mailbox$FolderCache not found" - ); - throw new RuntimeException(); - } - else - { - //do not avoid the exception - sFolderCacheMap = cls.getDeclaredField("mapById"); - sFolderCacheMap.setAccessible(true); - } - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } + return mMbox.getTagCache(); } /* * Warning: unsynchronized private access to mailbox */ @Nullable - private final Collection getFolderCache() + private Collection getFolderCache() { try { - Collection folders = Collections.emptyList(); - folders = (Collection) (((Map) sFolderCacheMap - .get(sFolderCache.get(mMbox))).values()); - ArrayList newList = new ArrayList(folders.size()); + Collection folders = mMbox.getCacheFolders(); + ArrayList newList = new ArrayList<>(folders.size()); - for (Object folder : folders) + for (com.zimbra.cs.mailbox.Folder folder : folders) { if ( folder != null) { @@ -2502,57 +1922,24 @@ private final Collection getFolderCache() @Nullable public static Mailbox getByAccount(@Nonnull Account account) - throws ZimbraException + throws ZimbraException { return getByAccount(account, true); } - @Nullable - public static Mailbox getByAccountId(String id) - throws ZimbraException - { - return getByAccountId(id, true); - } - - @Nullable - public static Mailbox getByAccountId(String id, boolean autocreate) - throws ZimbraException - { - com.zimbra.cs.mailbox.Mailbox mbox; - try - { - mbox = com.zimbra.cs.mailbox.MailboxManager.getInstance().getMailboxByAccountId( - id, - autocreate ? com.zimbra.cs.mailbox.MailboxManager.FetchMode.AUTOCREATE : - com.zimbra.cs.mailbox.MailboxManager.FetchMode.DO_NOT_AUTOCREATE - ); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - - if (mbox != null) - { - return new Mailbox(mbox); - } - - return null; - } - @Nullable @Deprecated public static Mailbox getByAccount(@Nonnull Account account, boolean autocreate) - throws ZimbraException + throws ZimbraException { com.zimbra.cs.mailbox.Mailbox mbox; try { mbox = com.zimbra.cs.mailbox.MailboxManager.getInstance().getMailboxByAccount( - account.toZimbra(com.zimbra.cs.account.Account.class) + account.toZimbra(com.zimbra.cs.account.Account.class) ); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2566,7 +1953,7 @@ public static Mailbox getByAccount(@Nonnull Account account, boolean autocreate) @Nullable @Deprecated public static Mailbox getById(long mboxId) - throws ZimbraException + throws ZimbraException { return getById((int) mboxId); } @@ -2574,14 +1961,14 @@ public static Mailbox getById(long mboxId) @Nullable @Deprecated public static Mailbox getById(int mboxId) - throws ZimbraException + throws ZimbraException { com.zimbra.cs.mailbox.Mailbox mbox; try { mbox = com.zimbra.cs.mailbox.MailboxManager.getInstance().getMailboxById(mboxId); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2601,14 +1988,14 @@ public static Mailbox getByItem(@Nonnull Item item) @Deprecated public static Map getMapAccountsAndMailboxes(@Nonnull Connection conn) - throws ZimbraException + throws ZimbraException { Map accountsAndMailboxes; try { accountsAndMailboxes = DbMailbox.listMailboxes(conn.toZimbra(DbPool.DbConnection.class)); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2618,14 +2005,14 @@ public static Map getMapAccountsAndMailboxes(@Nonnull Connectio @Nonnull public Connection getOperationConnection() - throws ZimbraException + throws ZimbraException { DbPool.DbConnection connection; try { connection = mMbox.getOperationConnection(); } - catch (com.zimbra.common.service.ServiceException e) + catch (ServiceException e) { throw ExceptionWrapper.wrap(e); } @@ -2635,46 +2022,13 @@ public Connection getOperationConnection() public int getSchemaGroupId() { //leave the cast - return (int) mMbox.getSchemaGroupId(); - } - - public void updateChat(@Nonnull OperationContext operationContext, @Nonnull ParsedMessage parsedMessage, int id) - throws IOException, ZimbraException - { - try - { - mMbox.updateChat( - operationContext.getOperationContext(), - parsedMessage.toZimbra(com.zimbra.cs.mime.ParsedMessage.class), - id - ); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public void reindexItem(@Nonnull Item item) - throws ZimbraException - { - List list = new ArrayList(); - - list.add(item.getId()); - try - { - mMbox.index.startReIndexById(list); - } - catch (com.zimbra.common.service.ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } + return mMbox.getSchemaGroupId(); } public String rawGetConfig( - @Nonnull String key + @Nonnull String key ) - throws SQLException, ZimbraException + throws SQLException, ZimbraException { String query = "SELECT metadata FROM zimbra.mailbox_metadata WHERE mailbox_id=? AND section=? LIMIT 1"; Connection connection = null; @@ -2711,10 +2065,10 @@ public String rawGetConfig( public static final long MAX_METADATA_SIZE = 16777215; public void rawSetConfig( - @Nonnull String section, - @Nullable String metadata + @Nonnull String section, + @Nullable String metadata ) - throws SQLException, ZimbraException + throws SQLException, ZimbraException { if (metadata != null && metadata.length() > MAX_METADATA_SIZE) { @@ -2807,10 +2161,6 @@ public void startReIndex() } } - public void deleteIndex() throws IOException, ZimbraException - { - mMbox.index.deleteIndex(); - } public void suspendIndexing() { mMbox.suspendIndexing(); @@ -2830,43 +2180,6 @@ public short getIndexVolume() { return mMbox.getIndexVolume(); } - public boolean isInMaintenanceMode() - { - com.zimbra.cs.mailbox.MailboxMaintenance maintenace = mMbox.getMaintenance(); - return maintenace != null; - } - - public void checkSizeChange(long newSize) throws ZimbraException - { - try - { - mMbox.checkSizeChangeOnAddOperation(newSize); - } - catch (ServiceException e) - { - throw ExceptionWrapper.wrap(e); - } - } - - public void createDefaultFlags() throws ZimbraException - { - try - { - beginTransaction("createDefaultFlags", newOperationContext()); - sCreateDefaultFlags.invoke(mMbox); - endTransaction(true); - } - catch( Exception e ) - { - endTransaction(false); - if( e instanceof ServiceException ) - { - throw ExceptionWrapper.wrap(e); - } - throw new RuntimeException(e); - } - } - public void purgeImapDeleted(OperationContext operationContext) { try{ mMbox.purgeImapDeleted(operationContext.getOperationContext()); @@ -2898,4 +2211,4 @@ public void markMailboxDeleted() throws org.openzal.zal.exceptions.ServiceExcept throw new org.openzal.zal.exceptions.ServiceException(e); } } -} +} \ No newline at end of file diff --git a/src/main/java/org/openzal/zal/MailboxManagerImp.java b/src/main/java/org/openzal/zal/MailboxManagerImp.java index dc94cce..b05f9d2 100644 --- a/src/main/java/org/openzal/zal/MailboxManagerImp.java +++ b/src/main/java/org/openzal/zal/MailboxManagerImp.java @@ -24,8 +24,6 @@ import com.zimbra.common.service.ServiceException; import com.zimbra.cs.db.DbMailbox; import com.zimbra.cs.db.DbPool; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; import org.apache.commons.dbutils.DbUtils; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -33,19 +31,13 @@ import org.openzal.zal.exceptions.NoSuchMailboxException; import org.openzal.zal.exceptions.ZimbraException; import org.openzal.zal.lib.ZimbraDatabase; -import org.openzal.zal.log.ZimbraLog; -import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; @SuppressWarnings({"StaticVariableOfConcreteClass", "StaticNonFinalField", "Singleton"}) public class MailboxManagerImp implements MailboxManager @@ -93,28 +85,6 @@ public MailboxManagerImp() mListenerMap = new HashMap(); } - private static final Field sMaintenanceLocks; - private static final Field sMailboxIds; - private static final Field sCache; - - static - { - try - { - sMaintenanceLocks = com.zimbra.cs.mailbox.MailboxManager.class.getDeclaredField("maintenanceLocks"); - sMailboxIds = com.zimbra.cs.mailbox.MailboxManager.class.getDeclaredField("mailboxIds"); - sCache = com.zimbra.cs.mailbox.MailboxManager.class.getDeclaredField("cache"); - sMaintenanceLocks.setAccessible(true); - sMailboxIds.setAccessible(true); - sCache.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public MailboxManagerImp(Object mailboxManager) { mMailboxManager = (com.zimbra.cs.mailbox.MailboxManager) mailboxManager; @@ -439,19 +409,7 @@ public void forceDeleteMailbox(@Nonnull MailboxData data) /* Remove mailbox entry from mailbox manager caches, it never existed....muhahaha */ - try - { - synchronized (mMailboxManager) - { - ((ConcurrentHashMap) (sMaintenanceLocks.get(mMailboxManager))).remove(data.getAccountId()); - ((Map) (sMailboxIds.get(mMailboxManager))).remove(data.getAccountId()); - ((Map) (sCache.get(mMailboxManager))).remove(data.getId()); - } - } - catch (Throwable ex) - { - throw new RuntimeException(ex); - } + mMailboxManager.removeMailboxData(data.getId(), data.getAccountId()); } @Override @@ -472,19 +430,7 @@ public void createMailboxWithSpecificId(Connection connection, Account account, throw ExceptionWrapper.wrap(e); } - try - { - synchronized (mMailboxManager) - { - ((ConcurrentHashMap) (sMaintenanceLocks.get(mMailboxManager))).remove(account.getId()); - ((Map) (sMailboxIds.get(mMailboxManager))).put(account.getId().toLowerCase(), (int)mailboxId); - ((Map) (sCache.get(mMailboxManager))).remove((int)mailboxId); - } - } - catch (Throwable ex) - { - throw new RuntimeException(ex); - } + mMailboxManager.setupMailboxWithSpecificId(mailboxId, account.getId().toLowerCase()); } } diff --git a/src/main/java/org/openzal/zal/ProvisioningImp.java b/src/main/java/org/openzal/zal/ProvisioningImp.java index 84ec527..c7ab5a0 100644 --- a/src/main/java/org/openzal/zal/ProvisioningImp.java +++ b/src/main/java/org/openzal/zal/ProvisioningImp.java @@ -79,7 +79,6 @@ import org.openzal.zal.exceptions.ZimbraException; import org.openzal.zal.lib.Filter; import org.openzal.zal.log.ZimbraLog; -import org.openzal.zal.provisioning.DirectQueryFilterBuilder; public class ProvisioningImp implements Provisioning @@ -3031,7 +3030,7 @@ public int rawCountQuery(String base, final String query) zlc = getLdapClient().getContext(LdapServerType.REPLICA, LdapUsage.GENERIC); return (int)zlc.countEntries( base, - DirectQueryFilterBuilder.create(query), + createZLdapFilter(query), searchControls ); } @@ -3049,6 +3048,14 @@ public int rawCountQuery(String base, final String query) } } + private static ZLdapFilter createZLdapFilter(String query) throws LDAPException + { + return new ZLdapFilter( + ZLdapFilterFactory.FilterId.TODO, + com.unboundid.ldap.sdk.Filter.create(query) + ); + } + @Override public void registerChangePasswordListener(ChangePasswordListener listener) { diff --git a/src/main/java/org/openzal/zal/StagedBlobWrap.java b/src/main/java/org/openzal/zal/StagedBlobWrap.java index 561a2ea..1104c98 100644 --- a/src/main/java/org/openzal/zal/StagedBlobWrap.java +++ b/src/main/java/org/openzal/zal/StagedBlobWrap.java @@ -20,7 +20,8 @@ package org.openzal.zal; -import com.zimbra.cs.store.file.VolumeBlobProxy; +import com.zimbra.cs.store.file.VolumeBlob; + import javax.annotation.Nonnull; import java.io.File; @@ -59,7 +60,7 @@ public String getDigest() @Override public InputStream getInputStream() throws IOException { - return new VolumeBlobProxy(mStagedBlob.getLocalBlob()).getInputStream(); + return new VolumeBlob(mStagedBlob.getLocalBlob()).getInputStream(); } @Override @@ -87,15 +88,12 @@ public StagedBlobWrap setSize(long size) } @Override - public long getStoredFileSize() throws IOException - { + public long getStoredFileSize() { return mStagedBlob.getSize(); } @Override - public boolean isCompressed() - throws IOException - { + public boolean isCompressed() { return false; } diff --git a/src/main/java/com/zimbra/cs/store/file/VolumeBlobProxy.java b/src/main/java/org/openzal/zal/VolumeBlobUtils.java similarity index 70% rename from src/main/java/com/zimbra/cs/store/file/VolumeBlobProxy.java rename to src/main/java/org/openzal/zal/VolumeBlobUtils.java index 23f9164..88c901a 100644 --- a/src/main/java/com/zimbra/cs/store/file/VolumeBlobProxy.java +++ b/src/main/java/org/openzal/zal/VolumeBlobUtils.java @@ -18,27 +18,16 @@ * along with ZAL. If not, see . */ -package com.zimbra.cs.store.file; +package org.openzal.zal; + +import com.zimbra.cs.store.file.VolumeBlob; import java.io.File; -public class VolumeBlobProxy extends VolumeBlob +public class VolumeBlobUtils { - public VolumeBlobProxy() - { - super(new File("/tmp/fakeblob"), (short) 0); - } - - public VolumeBlobProxy(Object blob) - { - super(((VolumeBlob)blob).getFile(), ((VolumeBlob)blob).getVolumeId()); - } - - @Override - public short getVolumeId() - { - return super.getVolumeId(); - } + public static final File VOLUME_BLOB_DEFAULT_FILE = new File("/tmp/fakeblob"); + public static final short VOLUME_BLOB_DEFAULT_VOLUME_ID = (short) 0; public static boolean isVolumeBlob(Object blob) { diff --git a/src/main/java/org/openzal/zal/VolumeManager.java b/src/main/java/org/openzal/zal/VolumeManager.java index 0d188cd..fd609f0 100644 --- a/src/main/java/org/openzal/zal/VolumeManager.java +++ b/src/main/java/org/openzal/zal/VolumeManager.java @@ -20,18 +20,15 @@ package org.openzal.zal; -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.*; import javax.annotation.Nullable; + +import com.zimbra.common.service.ServiceException; import org.openzal.zal.exceptions.*; -import org.openzal.zal.exceptions.VolumeServiceException; import org.openzal.zal.exceptions.ZimbraException; import com.zimbra.cs.volume.*; -import org.openzal.zal.log.ZimbraLog; public class VolumeManager { @@ -40,20 +37,6 @@ public class VolumeManager private static final short sFileGroupBits = 8; private static final short sFileBits = 12; - private static Method sVolumeManagerLoad = null; - static - { - try - { - sVolumeManagerLoad = com.zimbra.cs.volume.VolumeManager.class.getDeclaredMethod("load"); - sVolumeManagerLoad.setAccessible(true); - } - catch( Throwable t ) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(t)); - } - } - private final com.zimbra.cs.volume.VolumeManager mVolumeManager; public VolumeManager() @@ -63,13 +46,10 @@ public VolumeManager() public void reload() { - try - { - sVolumeManagerLoad.invoke(mVolumeManager); - } - catch( IllegalAccessException | InvocationTargetException e ) - { - throw new RuntimeException(e); + try { + mVolumeManager.load(); + } catch (ServiceException e) { + throw ExceptionWrapper.wrap(e); } } diff --git a/src/main/java/org/openzal/zal/calendar/Invite.java b/src/main/java/org/openzal/zal/calendar/Invite.java index 05804b6..f59585c 100644 --- a/src/main/java/org/openzal/zal/calendar/Invite.java +++ b/src/main/java/org/openzal/zal/calendar/Invite.java @@ -33,11 +33,23 @@ import com.zimbra.cs.mailbox.calendar.ZAttendee; import com.zimbra.cs.mailbox.calendar.ZOrganizer; import com.zimbra.cs.mailbox.calendar.ZRecur; +import org.openzal.zal.Account; +import org.openzal.zal.Item; +import org.openzal.zal.Provisioning; +import org.openzal.zal.ProvisioningImp; +import org.openzal.zal.ZimbraListWrapper; +import org.openzal.zal.exceptions.ExceptionWrapper; +import org.openzal.zal.exceptions.ZimbraException; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.io.Writer; -import java.lang.reflect.Field; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; @@ -50,26 +62,10 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import org.openzal.zal.Account; -import org.openzal.zal.Item; -import org.openzal.zal.Provisioning; -import org.openzal.zal.ProvisioningImp; -import org.openzal.zal.Utils; -import org.openzal.zal.ZimbraListWrapper; -import org.openzal.zal.exceptions.ExceptionWrapper; -import org.openzal.zal.exceptions.ZimbraException; -import org.openzal.zal.log.ZimbraLog; public class Invite { - private static String TRIGGER_TYPE_FIELD = "mTriggerType"; - private static String TRIGGER_RELATED_FIELD = "mTriggerRelated"; - public static int TYPE_EXCEPTION = Recurrence.TYPE_EXCEPTION; + public static final int TYPE_EXCEPTION = Recurrence.TYPE_EXCEPTION; public static int TYPE_CANCELLATION = Recurrence.TYPE_CANCELLATION; @Nullable @@ -81,26 +77,6 @@ public MimeMessage getAttachment() private final MimeMessage mMimeMessage; private final com.zimbra.cs.mailbox.calendar.Invite mInvite; - private static Field sTriggerTypeField = null; - private static Field sTriggerRelatedField = null; - - static - { - try - { - sTriggerTypeField = Alarm.class.getDeclaredField(TRIGGER_TYPE_FIELD); - sTriggerRelatedField = Alarm.class.getDeclaredField(TRIGGER_RELATED_FIELD); - - sTriggerTypeField.setAccessible(true); - sTriggerRelatedField.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public Invite(Object invite) { this(invite, null); @@ -213,28 +189,13 @@ public boolean hasAlarm() return false; } - private Alarm.TriggerType getTriggerType(Alarm alarm) - { - try - { - return (Alarm.TriggerType) sTriggerTypeField.get(alarm); - } - catch (Throwable e) - { - throw new RuntimeException(e); - } + private Alarm.TriggerType getTriggerType(Alarm alarm) { + return alarm.getTriggerType(); } private Alarm.TriggerRelated getTriggerRelated(Alarm alarm) { - try - { - return (Alarm.TriggerRelated) sTriggerRelatedField.get(alarm); - } - catch (Throwable e) - { - throw new RuntimeException(e); - } + return alarm.getTriggerRelated(); } private Alarm getDisplayAlarm() @@ -977,8 +938,7 @@ public void addAlarm(Map metadata) } } - public void updateMyPartStat(Account acct, String partStat) throws ServiceException - { + public void updateMyPartStat(Account acct, String partStat) { try { mInvite.updateMyPartStat(acct.toZimbra(com.zimbra.cs.account.Account.class), partStat); diff --git a/src/main/java/org/openzal/zal/extension/BootstrapClassLoader.java b/src/main/java/org/openzal/zal/extension/BootstrapClassLoader.java index 877a941..1cfe300 100644 --- a/src/main/java/org/openzal/zal/extension/BootstrapClassLoader.java +++ b/src/main/java/org/openzal/zal/extension/BootstrapClassLoader.java @@ -21,14 +21,10 @@ package org.openzal.zal.extension; import javax.annotation.Nonnull; -import org.openzal.zal.Utils; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.net.URL; import java.security.AllPermission; import java.security.CodeSigner; diff --git a/src/main/java/org/openzal/zal/extension/InternalOverrideStoreManager.java b/src/main/java/org/openzal/zal/extension/InternalOverrideStoreManager.java index 74d7da4..1133376 100644 --- a/src/main/java/org/openzal/zal/extension/InternalOverrideStoreManager.java +++ b/src/main/java/org/openzal/zal/extension/InternalOverrideStoreManager.java @@ -30,11 +30,8 @@ import com.zimbra.cs.store.MailboxBlob.MailboxBlobInfo; import com.zimbra.cs.store.StagedBlob; import com.zimbra.cs.store.StoreManager; -import com.zimbra.cs.store.file.VolumeStagedBlob; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; import java.util.Iterator; import org.openzal.zal.BlobWrap; import org.openzal.zal.MailboxBlobWrap; @@ -43,7 +40,6 @@ import org.openzal.zal.PrimaryStore; import org.openzal.zal.StagedBlobWrap; import org.openzal.zal.Store; -import org.openzal.zal.StoreFeature; import org.openzal.zal.StoreVolume; import org.openzal.zal.Utils; import org.openzal.zal.VolumeManager; @@ -130,19 +126,19 @@ private boolean supportedByAll(StoreFeature feature) return true; } - public BlobBuilder getBlobBuilder() throws IOException, ServiceException + public BlobBuilder getBlobBuilder() throws IOException { return mStoreManager.getPrimaryStore().getBlobBuilder().toZimbra(BlobBuilder.class); } public Blob storeIncoming(InputStream data, boolean storeAsIs) - throws IOException, ServiceException + throws IOException { return mStoreManager.getPrimaryStore().storeIncoming(data, storeAsIs).toZimbra(Blob.class); } public StagedBlob stage(InputStream data, long actualSize, Mailbox mbox) - throws IOException, ServiceException + throws IOException { return mStoreManager.getPrimaryStore().stage( mStoreManager.getPrimaryStore().storeIncoming(data, false), @@ -150,7 +146,7 @@ public StagedBlob stage(InputStream data, long actualSize, Mailbox mbox) ).toZimbra(StagedBlob.class); } - public StagedBlob stage(Blob blob, Mailbox mbox) throws IOException, ServiceException + public StagedBlob stage(Blob blob, Mailbox mbox) throws IOException { return mStoreManager.getPrimaryStore().stage( BlobWrap.wrapZimbraBlob(blob), @@ -241,30 +237,6 @@ public boolean delete(Blob blob) throws IOException ); } - private static final Method mVolumeStagedBlobWasStagedDirectlyMethod; - private static final Constructor mMailServiceException; - //private static final Method mExternalStagedBlobIsInsertedMethod; - - static - { - try - { - mVolumeStagedBlobWasStagedDirectlyMethod = VolumeStagedBlob.class.getDeclaredMethod("wasStagedDirectly"); - mMailServiceException = MailServiceException.class.getDeclaredConstructor( - String.class, String.class, boolean.class, Throwable.class, MailServiceException.Argument[].class - ); - //mExternalStagedBlobIsInsertedMethod = ExternalStagedBlob.class.getDeclaredMethod("isInserted"); - - mVolumeStagedBlobWasStagedDirectlyMethod.setAccessible(true); - mMailServiceException.setAccessible(true); - //mExternalStagedBlobIsInsertedMethod.setAccessible(true); - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("ZAL reflection error " + Utils.exceptionToString(e)); - } - } - public boolean delete(StagedBlob staged) throws IOException { if (staged == null) @@ -285,7 +257,7 @@ public boolean delete(MailboxBlob blob) throws IOException } @Nullable - public MailboxBlob getMailboxBlob(Mailbox mbox, int itemId, int revision, String locator) throws ServiceException + public MailboxBlob getMailboxBlob(Mailbox mbox, int itemId, int revision, String locator) { try { @@ -309,14 +281,12 @@ public MailboxBlob getMailboxBlob(Mailbox mbox, int itemId, int revision, String } public MailboxBlob getMailboxBlob(Mailbox mailbox, int itemId, int revision, String locator, boolean validate) - throws ServiceException { return getMailboxBlob(mailbox, itemId, revision, locator); } @Nullable - public MailboxBlob getMailboxBlob(MailItem mailItem) throws ServiceException - { + public MailboxBlob getMailboxBlob(MailItem mailItem) { MailboxBlob blob = getMailboxBlob( mailItem.getMailbox(), mailItem.getId(), mailItem.getSavedSequence(), mailItem.getLocator() ); @@ -332,8 +302,7 @@ public MailboxBlob getMailboxBlob(MailItem mailItem) throws ServiceException } @Nullable - public InputStream getContent(MailboxBlob mboxBlob) throws IOException - { + public InputStream getContent(MailboxBlob mboxBlob) { org.openzal.zal.MailboxBlob zalMailboxBlob = MailboxBlobWrap.wrapZimbraObject(mboxBlob); try { @@ -348,7 +317,7 @@ public InputStream getContent(MailboxBlob mboxBlob) throws IOException arguments[0] = new ServiceException.Argument(ITEM_ID, zalMailboxBlob.getItemId(), ServiceException.Argument.Type.IID); arguments[1] = new ServiceException.Argument(REVISION, zalMailboxBlob.getRevision(), ServiceException.Argument.Type.NUM); AnyThrow.throwUnchecked( - (Throwable) mMailServiceException.newInstance( + MailServiceException.mailServiceException( "No such blob: mailbox=" + zalMailboxBlob.getMailbox().getId() + "," + " item=" + zalMailboxBlob.getItemId() + ", change=" + zalMailboxBlob.getRevision(), NO_SUCH_BLOB, SENDERS_FAULT, @@ -365,8 +334,7 @@ public InputStream getContent(MailboxBlob mboxBlob) throws IOException } } - public InputStream getContent(Blob blob) throws IOException - { + public InputStream getContent(Blob blob) { org.openzal.zal.Blob zalBlob = BlobWrap.wrapZimbraBlob(blob); if (zalBlob.hasMailboxInfo()) { @@ -387,7 +355,7 @@ public InputStream getContent(Blob blob) throws IOException arguments[0] = new ServiceException.Argument(ITEM_ID, zalMailboxBlob.getItemId(), ServiceException.Argument.Type.IID); arguments[1] = new ServiceException.Argument(REVISION, zalMailboxBlob.getRevision(), ServiceException.Argument.Type.NUM); AnyThrow.throwUnchecked( - (Throwable) mMailServiceException.newInstance( + MailServiceException.mailServiceException( "No such blob: mailbox=" + zalMailboxBlob.getMailbox().getId() + "," + " item=" + zalMailboxBlob.getItemId() + ", change=" + zalMailboxBlob.getRevision(), NO_SUCH_BLOB, SENDERS_FAULT, @@ -423,7 +391,7 @@ public InputStream getContent(Blob blob) throws IOException arguments[0] = new ServiceException.Argument("volumeId", zalBlob.getVolumeId(), ServiceException.Argument.Type.STR); arguments[1] = new ServiceException.Argument("blobPath", zalBlob.getKey(), ServiceException.Argument.Type.STR); AnyThrow.throwUnchecked( - (Throwable) mMailServiceException.newInstance( + MailServiceException.mailServiceException( "No such blob: " + zalBlob.getKey() + ", volume=" + zalBlob.getVolumeId(), NO_SUCH_BLOB, false, diff --git a/src/main/java/org/openzal/zal/extension/StoreManagerImpl.java b/src/main/java/org/openzal/zal/extension/StoreManagerImpl.java index 311509e..86dde49 100644 --- a/src/main/java/org/openzal/zal/extension/StoreManagerImpl.java +++ b/src/main/java/org/openzal/zal/extension/StoreManagerImpl.java @@ -21,10 +21,7 @@ package org.openzal.zal.extension; import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -32,7 +29,6 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiFunction; import java.util.function.Function; -import org.apache.commons.io.IOUtils; import org.openzal.zal.CacheableStoreBuilder; import org.openzal.zal.FileBlobPrimaryStore; import org.openzal.zal.FileBlobStoreWrap; @@ -54,52 +50,6 @@ public class StoreManagerImpl implements StoreManager private PrimaryStoreBuilder mPrimaryStoreBuilder; - static - { - try - { - Method defineClassMethod = ClassLoader.class.getDeclaredMethod( - "defineClass", byte[].class, int.class, int.class - ); - defineClassMethod.setAccessible(true); - - InputStream is = null; - try - { - Class parentClass = Class.forName("com.zimbra.cs.store.file.VolumeBlob"); - ClassLoader parentClassLoader = parentClass.getClassLoader(); - - is = BootstrapClassLoader.class.getResourceAsStream("/com/zimbra/cs/store/file/VolumeBlobProxy"); - byte[] buffer = new byte[6 * 1024]; - int idx = 0; - int read = 0; - while (read > -1) - { - idx += read; - if (buffer.length == idx) - { - buffer = Arrays.copyOf(buffer, buffer.length * 2); - } - read = is.read(buffer, idx, buffer.length - idx); - } - - defineClassMethod.invoke( - parentClassLoader, - buffer, 0, idx - ); - } - catch (Exception ignore) {} - finally - { - IOUtils.closeQuietly(is); - } - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - public StoreManagerImpl( final FileBlobStoreWrap fileBlobStore, VolumeManager volumeManager diff --git a/src/main/java/org/openzal/zal/extension/Zimbra.java b/src/main/java/org/openzal/zal/extension/Zimbra.java index 1797b1a..ea97b21 100644 --- a/src/main/java/org/openzal/zal/extension/Zimbra.java +++ b/src/main/java/org/openzal/zal/extension/Zimbra.java @@ -23,17 +23,13 @@ import com.zimbra.cs.extension.ExtensionUtil; import com.zimbra.cs.extension.ZimbraExtension; import com.zimbra.cs.store.file.FileBlobStore; -import java.lang.reflect.Field; -import java.util.Map; import org.openzal.zal.FileBlobStoreWrapImpl; import org.openzal.zal.MailboxManager; import org.openzal.zal.MailboxManagerImp; import org.openzal.zal.Provisioning; import org.openzal.zal.ProvisioningImp; import org.openzal.zal.StoreManager; -import org.openzal.zal.Utils; import org.openzal.zal.VolumeManager; -import org.openzal.zal.lib.PermissiveMap; import org.openzal.zal.lib.ZimbraDatabase; import org.openzal.zal.log.ZimbraLog; @@ -100,46 +96,9 @@ public Zimbra(Zimbra zimbra) } } - private static final Field sIsMailboxd; - - static - { - try - { - sIsMailboxd = com.zimbra.cs.util.Zimbra.class.getDeclaredField("sIsMailboxd"); - sIsMailboxd.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - public void forceMailboxd() - { - try - { - sIsMailboxd.set(null, true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public boolean isMailboxd() { - try - { - return sIsMailboxd.getBoolean(null); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } + return com.zimbra.cs.util.Zimbra.isMailboxd(); } @Nonnull @@ -185,87 +144,14 @@ public boolean shutdownExtension(String extensionName) return false; } - private static Field sInitializedExtensions; - - static - { - try - { - Class cls = com.zimbra.cs.extension.ExtensionUtil.class; - sInitializedExtensions = cls.getDeclaredField("sInitializedExtensions"); - sInitializedExtensions.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - private static Field sStoreManagerInstance; - - static - { - try - { - sStoreManagerInstance = com.zimbra.cs.store.StoreManager.class.getDeclaredField("sInstance"); - sStoreManagerInstance.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - private static Field sRedoLogProviderInstance; - - static - { - try - { - sRedoLogProviderInstance = com.zimbra.cs.redolog.RedoLogProvider.class.getDeclaredField("theInstance"); - sRedoLogProviderInstance.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public boolean removeExtension(String extensionName) { - try - { - return ((Map) sInitializedExtensions.get(null)).remove(extensionName) != null; - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } + return ExtensionUtil.removeExtension(extensionName); } public static void overrideExtensionMap() { -/* - ZX-3303 - avoid concurrent modification exception when disabling an extension - during extension postInit -*/ - - try - { - Map map = (Map)sInitializedExtensions.get(null); - sInitializedExtensions.set( - null, - new PermissiveMap(map) - ); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } + ExtensionUtil.clearExtensions(); } public void overrideZimbraStoreManager() @@ -278,15 +164,7 @@ public void overrideZimbraStoreManager() public void overrideZimbraRedoLogProvider(RedoLogProvider redoLogProvider) { ZimbraLog.extensions.info("ZAL override Zimbra RedoLog"); - try - { - sRedoLogProviderInstance.set(null, redoLogProvider); - } - catch( IllegalAccessException e ) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(e)); - throw new RuntimeException(e); - } + com.zimbra.cs.redolog.RedoLogProvider.setInstance(redoLogProvider); } public void overrideZimbraStoreManager(StoreManager storeManager) @@ -298,27 +176,12 @@ public void overrideZimbraStoreManager(StoreManager storeManager) } mInternalOverrideStoreManager = new InternalOverrideStoreManager(storeManager, mVolumeManager); ZimbraLog.extensions.info("ZAL override Zimbra StoreManager"); - try - { - sStoreManagerInstance.set(null, mInternalOverrideStoreManager); - mStoreManager = storeManager; - } - catch( IllegalAccessException e ) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(e)); - throw new RuntimeException(e); - } + com.zimbra.cs.store.StoreManager.setInstance(mInternalOverrideStoreManager); + mStoreManager = storeManager; } public void restoreZimbraStoreManager() { - try - { - sStoreManagerInstance.set(null, mZimbraStoreManager); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } + com.zimbra.cs.store.StoreManager.setInstance(mZimbraStoreManager); } } diff --git a/src/main/java/org/openzal/zal/index/IndexerManager.java b/src/main/java/org/openzal/zal/index/IndexerManager.java index fe64433..e42da72 100644 --- a/src/main/java/org/openzal/zal/index/IndexerManager.java +++ b/src/main/java/org/openzal/zal/index/IndexerManager.java @@ -21,18 +21,12 @@ package org.openzal.zal.index; import com.zimbra.cs.convert.AttachmentInfo; -import com.zimbra.cs.convert.ConversionException; import com.zimbra.cs.mime.*; import org.apache.lucene.document.Document; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.openzal.zal.Utils; -import org.openzal.zal.log.ZimbraLog; import javax.activation.DataSource; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -41,19 +35,10 @@ public class IndexerManager { - private static final Field sMimeHandlerManagerHandlersField; - private static final Class sMimeHandlerManager; - - private static final Class sHandlerInfo; - private static final Constructor sHandlerInfoConstructor; - private static final Field sHandlerInfoClazzField; - private static final Field sHandlerInfoContentTypeField; - private static final Field sHandlerInfoRealMimeTypeField; - - private static final List sIndexerList; + private static final List sIndexerList = Collections.synchronizedList(new LinkedList()); @Nullable - private static Map sOriginalMap; + private static Map sOriginalMap; public void register(Indexer indexer) @@ -66,71 +51,20 @@ public void unregister(Indexer indexer) sIndexerList.remove(indexer); } - - static - { - try - { - sOriginalMap = null; - sIndexerList = Collections.synchronizedList(new LinkedList()); - - sMimeHandlerManager = com.zimbra.cs.mime.MimeHandlerManager.class; - sHandlerInfo = sMimeHandlerManager.getClassLoader().loadClass("com.zimbra.cs.mime.MimeHandlerManager$HandlerInfo"); - - sHandlerInfoConstructor = sHandlerInfo.getDeclaredConstructors()[0]; - sHandlerInfoConstructor.setAccessible(true); - - sMimeHandlerManagerHandlersField = sMimeHandlerManager.getDeclaredField("sHandlers"); - sMimeHandlerManagerHandlersField.setAccessible(true); - - sHandlerInfoClazzField = sHandlerInfo.getDeclaredField("clazz"); - sHandlerInfoClazzField.setAccessible(true); - - sHandlerInfoContentTypeField = sHandlerInfo.getDeclaredField("realMimeType"); - - sHandlerInfoContentTypeField.setAccessible(true); - - sHandlerInfoRealMimeTypeField = sHandlerInfo.getDeclaredField("mimeType"); - sHandlerInfoRealMimeTypeField.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public void attachToZimbra() { - try - { - sOriginalMap = (Map) sMimeHandlerManagerHandlersField.get(null); - sMimeHandlerManagerHandlersField.set( - null, - new IndexerProxyMap( - sOriginalMap, - new MimeHandlerProviderImpl() - ) - ); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } + sOriginalMap = MimeHandlerManager.getHandlers(); + MimeHandlerManager.setHandlers(new IndexerProxyMap( + sOriginalMap, + new MimeHandlerProviderImpl() + )); } public void detach() { - try + if( sOriginalMap != null ) { - if( sOriginalMap != null ) - { - sMimeHandlerManagerHandlersField.set(null, sOriginalMap); - } - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); + MimeHandlerManager.setHandlers(sOriginalMap); } } @@ -151,7 +85,7 @@ class MimeHandlerProviderImpl implements MimeHandlerProvider { @Nullable @Override - public Object getMimeHandlerFor(String contentType, String fileExtension) + public MimeHandlerManager.HandlerInfo getMimeHandlerFor(String contentType, String fileExtension) { Indexer indexer = getBestIndexer(contentType, fileExtension); if (indexer != null) @@ -166,16 +100,16 @@ public Object getMimeHandlerFor(String contentType, String fileExtension) } } - private Object createHandlerInfoProxy(Class cls, String contentType) + private MimeHandlerManager.HandlerInfo createHandlerInfoProxy(Class cls, String contentType) { try { - Object info = sHandlerInfoConstructor.newInstance(); + var info = new MimeHandlerManager.HandlerInfo(); - sHandlerInfoContentTypeField.set(info, contentType); - sHandlerInfoClazzField.set(info, cls); + info.setRealMimeType(contentType); + info.setClass(cls); - sHandlerInfoRealMimeTypeField.set(info, new MimeTypeInfo() { + info.setMimeType(new MimeTypeInfo() { @Override public String[] getMimeTypes() { return new String[0]; @@ -230,9 +164,8 @@ protected boolean runsExternally() return false; } - //this methods breaks binary compatibility for ZAL given two different parameters types @Override - protected void addFields(Document doc) throws MimeHandlerException + protected void addFields(Document doc) { } @@ -280,7 +213,7 @@ private String getExtension() } @Override - public String convert(AttachmentInfo doc, String urlPart) throws IOException, ConversionException + public String convert(AttachmentInfo doc, String urlPart) { throw new UnsupportedOperationException(); } diff --git a/src/main/java/org/openzal/zal/index/IndexerProxyMap.java b/src/main/java/org/openzal/zal/index/IndexerProxyMap.java index cc91513..906954b 100644 --- a/src/main/java/org/openzal/zal/index/IndexerProxyMap.java +++ b/src/main/java/org/openzal/zal/index/IndexerProxyMap.java @@ -20,17 +20,19 @@ package org.openzal.zal.index; +import com.zimbra.cs.mime.MimeHandlerManager; + import java.util.Collection; import java.util.Map; import java.util.Set; -class IndexerProxyMap implements Map +class IndexerProxyMap implements Map { - private final Map mMap; + private final Map mMap; private final MimeHandlerProvider mMimeHandlerProvider; IndexerProxyMap( - Map map, + Map map, MimeHandlerProvider mimeHandlerProvider ) { @@ -39,7 +41,7 @@ class IndexerProxyMap implements Map } @Override - public Object get(Object key) + public MimeHandlerManager.HandlerInfo get(Object key) { String strKey = (String) key; @@ -56,7 +58,7 @@ public Object get(Object key) fileExtension = data[1]; } - Object obj = mMimeHandlerProvider.getMimeHandlerFor( + MimeHandlerManager.HandlerInfo obj = mMimeHandlerProvider.getMimeHandlerFor( contentType, fileExtension ); @@ -95,19 +97,19 @@ public boolean containsValue(Object value) } @Override - public Object put(String key, Object value) + public MimeHandlerManager.HandlerInfo put(String key, MimeHandlerManager.HandlerInfo value) { return mMap.put(key, value); } @Override - public Object remove(Object key) + public MimeHandlerManager.HandlerInfo remove(Object key) { return mMap.remove(key); } @Override - public void putAll(Map m) + public void putAll(Map m) { mMap.putAll(m); } @@ -125,13 +127,13 @@ public Set keySet() } @Override - public Collection values() + public Collection values() { return mMap.values(); } @Override - public Set> entrySet() + public Set> entrySet() { return mMap.entrySet(); } diff --git a/src/main/java/org/openzal/zal/index/MimeHandlerProvider.java b/src/main/java/org/openzal/zal/index/MimeHandlerProvider.java index 97846d9..d4a7ac2 100644 --- a/src/main/java/org/openzal/zal/index/MimeHandlerProvider.java +++ b/src/main/java/org/openzal/zal/index/MimeHandlerProvider.java @@ -20,10 +20,12 @@ package org.openzal.zal.index; +import com.zimbra.cs.mime.MimeHandlerManager; + import javax.annotation.Nullable; public interface MimeHandlerProvider { @Nullable - Object getMimeHandlerFor(String contentType, String fileExtension); + MimeHandlerManager.HandlerInfo getMimeHandlerFor(String contentType, String fileExtension); } diff --git a/src/main/java/org/openzal/zal/lib/PermissiveMap.java b/src/main/java/org/openzal/zal/lib/PermissiveMap.java deleted file mode 100644 index b3062e8..0000000 --- a/src/main/java/org/openzal/zal/lib/PermissiveMap.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * ZAL - Zextras Abstraction Layer. - * Copyright (C) 2023 ZeXtras S.r.l. - * - * This file is part of ZAL. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ZAL. If not, see . - */ - -package org.openzal.zal.lib; - -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/* - This map allow object removing during iteration, doesn't throw ConcurrentModificationException - This map is NOT optimized for any usage, avoid using it unless necessary. - This map is NOT thread-safe. -*/ -public class PermissiveMap extends AbstractMap implements Map -{ - private final List mKeys; - private final List mValues; - - public PermissiveMap() - { - mKeys = new ArrayList(16); - mValues = new ArrayList(16); - } - - public PermissiveMap(Map map) - { - this(); - putAll(map); - } - - @Override - public int size() - { - return mKeys.size(); - } - - @Override - public boolean isEmpty() - { - return mKeys.isEmpty(); - } - - @Override - public boolean containsKey(Object key) - { - return mKeys.contains(key); - } - - @Override - public boolean containsValue(Object value) - { - return mValues.contains(value); - } - - @Override - public V get(Object key) - { - int idx = mKeys.indexOf(key); - return idx == -1 ? null : mValues.get(idx); - } - - @Override - public V put(K key, V value) - { - V old = null; - int idx = mKeys.indexOf(key); - if (idx != -1) - { - mKeys.remove(idx); - old = mValues.remove(idx); - } - mKeys.add(key); - mValues.add(value); - return old; - } - - @Override - public V remove(Object key) - { - int idx = mKeys.indexOf(key); - if (idx != -1) - { - mKeys.remove(idx); - return mValues.remove(idx); - } - return null; - } - - @Override - public void putAll(Map m) - { - for (Map.Entry entry : m.entrySet()) - { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void clear() - { - mKeys.clear(); - mValues.clear(); - } - - @Override - public Set keySet() - { - return new PermissiveSet(mKeys); - } - - @Override - public Collection values() - { - return new PermissiveSet(mValues); - } - - class IndexedEntry implements Entry - { - private final int mIdx; - private final K mKey; - private final V mValue; - - IndexedEntry(int idx, K key, V value) - { - mIdx = idx; - mKey = key; - mValue = value; - } - - @Override - public K getKey() - { - return mKey; - } - - @Override - public V getValue() - { - return mValue; - } - - @Override - public V setValue(V value) - { - V old = mValues.remove(mIdx); - mValues.add(mIdx, value); - return old; - } - - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - Entry that = (Entry) o; - - if (mKey != null ? !mKey.equals(that.getKey()) : that.getKey() != null) - return false; - return !(mValue != null ? !mValue.equals(that.getValue()) : that.getValue() != null); - } - - public int hashCode() - { - return (mKey == null ? 0 : mKey.hashCode()) ^ (mValue == null ? 0 : mValue.hashCode()); - } - } - - static class SimpleEntry implements Entry - { - private final K mKey; - private V mValue; - - SimpleEntry(K key, V value) - { - mKey = key; - mValue = value; - } - - @Override - public K getKey() - { - return mKey; - } - - @Override - public V getValue() - { - return mValue; - } - - @Override - public V setValue(V value) - { - V old = mValue; - mValue = value; - return old; - } - - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - Entry that = (Entry) o; - - if (mKey != null ? !mKey.equals(that.getKey()) : that.getKey() != null) - return false; - return !(mValue != null ? !mValue.equals(that.getValue()) : that.getValue() != null); - } - - public int hashCode() - { - return (mKey == null ? 0 : mKey.hashCode()) ^ (mValue == null ? 0 : mValue.hashCode()); - } - } - - class EntrySet extends AbstractSet> implements Set> - { - @Override - public int size() - { - return mKeys.size(); - } - - @Override - public boolean isEmpty() - { - return mKeys.isEmpty(); - } - - @Override - public boolean contains(Object o) - { - if (o instanceof Entry) - { - Entry entry = (Entry) o; - int idx = mKeys.indexOf(entry.getKey()); - if (idx != -1) - { - V value = mValues.get(idx); - return (value == null && entry.getValue() == null) || - ((value != null && entry.getValue() != null) && entry.getValue().equals(value)); - } - } - return false; - } - - @Override - public Iterator> iterator() - { - return new Iterator>() - { - int mIndex = 0; - - @Override - public boolean hasNext() - { - return mIndex < mKeys.size(); - } - - @Override - public Entry next() - { - IndexedEntry entry = new IndexedEntry( - mIndex, - mKeys.get(mIndex), - mValues.get(mIndex) - ); - mIndex++; - return entry; - } - - @Override - public void remove() - { - if (mIndex > 0) - { - --mIndex; - mKeys.remove(mIndex); - mValues.remove(mIndex); - } - else - { - throw new IllegalStateException(); - } - } - }; - } - - @Override - public boolean add(Entry kvEntry) - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) - { - Entry entry = (Entry) o; - int index = mKeys.indexOf(entry.getKey()); - if (index != -1) - { - V value = mValues.get(index); - V other = entry.getValue(); - if( value == other || (value != null && other != null && value.equals(other))) - { - mKeys.remove(index); - mValues.remove(index); - return true; - } - } - return false; - } - - @Override - public void clear() - { - PermissiveMap.this.clear(); - } - } - - @Override - public Set> entrySet() - { - return new EntrySet(); - } - - class PermissiveSet extends AbstractSet implements Set - { - private final List mList; - - public PermissiveSet(List list) - { - mList = list; - } - - @Override - public int size() - { - return mList.size(); - } - - @Override - public boolean isEmpty() - { - return mList.isEmpty(); - } - - @Override - public boolean contains(Object o) - { - return mList.contains(o); - } - - @Override - public Iterator iterator() - { - return new Iterator() - { - int mIndex = 0; - - @Override - public void remove() - { - if (mIndex > 0) - { - mIndex--; - mValues.remove(mIndex); - mKeys.remove(mIndex); - } - else - { - throw new IllegalStateException(); - } - } - - @Override - public boolean hasNext() - { - return mIndex < mList.size(); - } - - @Override - public X next() - { - return mList.get(mIndex++); - } - }; - } - - @Override - public Object[] toArray() - { - return mList.toArray(new Object[size()]); - } - - @Override - public T[] toArray(T[] a) - { - return mList.toArray(a); - } - - @Override - public boolean remove(Object o) - { - int index = mList.indexOf(o); - if (index != -1) - { - mValues.remove(index); - mKeys.remove(index); - return true; - } - return false; - } - - @Override - public void clear() - { - PermissiveMap.this.clear(); - } - } -} diff --git a/src/main/java/org/openzal/zal/lucene/index/IndexStore.java b/src/main/java/org/openzal/zal/lucene/index/IndexStore.java index 86b86ae..6e16727 100644 --- a/src/main/java/org/openzal/zal/lucene/index/IndexStore.java +++ b/src/main/java/org/openzal/zal/lucene/index/IndexStore.java @@ -35,11 +35,11 @@ public Document createDocument() } public Indexer openIndexer() - throws IOException, ZimbraException + throws ZimbraException { try { - return new Indexer(this, mIndex.openIndexer()); + return new Indexer(mIndex.openIndexer()); } catch( Exception e ) { @@ -47,9 +47,7 @@ public Indexer openIndexer() } } - public IndexSearcher openSearcher() - throws IOException - { + public IndexSearcher openSearcher() { try { return new IndexSearcher(mIndex.openSearcher()); diff --git a/src/main/java/org/openzal/zal/lucene/index/Indexer.java b/src/main/java/org/openzal/zal/lucene/index/Indexer.java index 6a1cd5e..8b8f40b 100644 --- a/src/main/java/org/openzal/zal/lucene/index/Indexer.java +++ b/src/main/java/org/openzal/zal/lucene/index/Indexer.java @@ -3,11 +3,11 @@ import java.io.Closeable; import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.StringJoiner; + +import com.zimbra.cs.index.LuceneIndex; import org.openzal.zal.Folder; import org.openzal.zal.Item; import org.openzal.zal.exceptions.ExceptionWrapper; @@ -20,41 +20,14 @@ public class Indexer implements Closeable { - private final IndexStore mIndexStore; - private final com.zimbra.cs.index.Indexer mIndexer; - - private Object mIndexWriterRef; - private Method mIndexWriterRefGet; + private final LuceneIndex.LuceneIndexerImpl mIndexer; - private IndexWriter mIndexWriter; + private final IndexWriter mIndexWriter; public Indexer(@Nonnull Object zObject) { - this(null, zObject); - } - - public Indexer(IndexStore indexStore, @Nonnull Object zObject) - { - mIndexStore = indexStore; - mIndexer = (com.zimbra.cs.index.Indexer) zObject; - - try - { - Field writer = zObject.getClass().getDeclaredField("writer"); - writer.setAccessible(true); - - mIndexWriterRef = writer.get(zObject); - - Class target = com.zimbra.cs.index.LuceneIndex.class.getClassLoader().loadClass("com.zimbra.cs.index.LuceneIndex$IndexWriterRef"); - mIndexWriterRefGet = target.getDeclaredMethod("get"); - mIndexWriterRefGet.setAccessible(true); - - mIndexWriter = getIndexWriter(); - } - catch( Exception e ) - { - throw ExceptionWrapper.wrap(e); - } + mIndexer = (LuceneIndex.LuceneIndexerImpl) zObject; + mIndexWriter = getIndexWriter(); } public void addDocument(Document document, Object... idParts) @@ -159,7 +132,7 @@ private IndexWriter getIndexWriter() { try { - return new IndexWriter(mIndexWriterRefGet.invoke(mIndexWriterRef)); + return new IndexWriter(mIndexer.getWriter().get()); } catch( Exception e ) { diff --git a/src/main/java/org/openzal/zal/provisioning/DirectQueryFilterBuilder.java b/src/main/java/org/openzal/zal/provisioning/DirectQueryFilterBuilder.java deleted file mode 100644 index cc82189..0000000 --- a/src/main/java/org/openzal/zal/provisioning/DirectQueryFilterBuilder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ZAL - Zextras Abstraction Layer. - * Copyright (C) 2023 ZeXtras S.r.l. - * - * This file is part of ZAL. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ZAL. If not, see . - */ - -package org.openzal.zal.provisioning; - -import com.unboundid.ldap.sdk.Filter; -import com.unboundid.ldap.sdk.LDAPException; -import com.zimbra.cs.ldap.ZLdapFilter; -import com.zimbra.cs.ldap.ZLdapFilterFactory; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import org.openzal.zal.exceptions.ExceptionWrapper; - -public abstract class DirectQueryFilterBuilder -{ - private static final Constructor mConstructor; - - static - { - mConstructor = ZLdapFilter.class.getDeclaredConstructors()[0]; - mConstructor.setAccessible(true); - } - - public static ZLdapFilter create(String query) throws LDAPException - { - try - { - return (ZLdapFilter)mConstructor.newInstance( - ZLdapFilterFactory.FilterId.TODO, - Filter.create(query) - ); - } - catch (InstantiationException|IllegalAccessException|InvocationTargetException e) - { - if( e.getCause() instanceof Exception) - { - throw ExceptionWrapper.wrap((java.lang.Exception)e.getCause()); - } - else - { - throw new RuntimeException(e); - } - } - } -} diff --git a/src/main/java/com/zimbra/cs/redolog/op/DataExtractor.java b/src/main/java/org/openzal/zal/redolog/DataExtractor.java similarity index 92% rename from src/main/java/com/zimbra/cs/redolog/op/DataExtractor.java rename to src/main/java/org/openzal/zal/redolog/DataExtractor.java index db9abf8..5cbf575 100644 --- a/src/main/java/com/zimbra/cs/redolog/op/DataExtractor.java +++ b/src/main/java/org/openzal/zal/redolog/DataExtractor.java @@ -18,10 +18,12 @@ * along with ZAL. If not, see . */ -package com.zimbra.cs.redolog.op; +package org.openzal.zal.redolog; import com.zimbra.cs.redolog.RedoLogOutput; +import com.zimbra.cs.redolog.op.RedoableOp; + import java.io.IOException; public class DataExtractor diff --git a/src/main/java/org/openzal/zal/redolog/op/ColorItem.java b/src/main/java/org/openzal/zal/redolog/op/ColorItem.java index b39ab95..0576896 100644 --- a/src/main/java/org/openzal/zal/redolog/op/ColorItem.java +++ b/src/main/java/org/openzal/zal/redolog/op/ColorItem.java @@ -22,8 +22,6 @@ import org.openzal.zal.MailItemType; -import java.lang.reflect.Field; - public class ColorItem { private final int[] ids; private final MailItemType type; @@ -38,24 +36,10 @@ public ColorItemInitializationException(Throwable cause) { } public ColorItem(RedoableOp op) { - Field field; - try { - field = com.zimbra.cs.redolog.op.ColorItem.class.getDeclaredField("mIds"); - field.setAccessible(true); - com.zimbra.cs.redolog.op.RedoableOp proxiedObject = op.getProxiedObject(); - ids = (int[]) field.get(proxiedObject); - - field = com.zimbra.cs.redolog.op.ColorItem.class.getDeclaredField("type"); - field.setAccessible(true); - com.zimbra.cs.mailbox.MailItem.Type type = (com.zimbra.cs.mailbox.MailItem.Type) field.get(proxiedObject); - this.type = new MailItemType(type); - field = com.zimbra.cs.redolog.op.ColorItem.class.getDeclaredField("mColor"); - field.setAccessible(true); - color = field.getLong(proxiedObject); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new ColorItemInitializationException(e); - } - + com.zimbra.cs.redolog.op.ColorItem colorItem = (com.zimbra.cs.redolog.op.ColorItem) op.getProxiedObject(); + this.ids = colorItem.getIds(); + this.type = new MailItemType(colorItem.getType()); + this.color = colorItem.getColor(); } public int[] getIds() { diff --git a/src/main/java/org/openzal/zal/redolog/op/RawSetConfig.java b/src/main/java/org/openzal/zal/redolog/op/RawSetConfig.java index 33c9edf..bd9c59c 100644 --- a/src/main/java/org/openzal/zal/redolog/op/RawSetConfig.java +++ b/src/main/java/org/openzal/zal/redolog/op/RawSetConfig.java @@ -31,7 +31,7 @@ public String getConfig() { } @Override - public void redo() throws Exception { + public void redo() { throw new UnsupportedOperationException(); } @@ -43,7 +43,7 @@ protected String getPrintableData() { } @Override - protected void serializeData(RedoLogOutput out) throws IOException { + public void serializeData(RedoLogOutput out) throws IOException { out.writeUTF(this.section); out.writeUTF(config != null ? config : ""); } diff --git a/src/main/java/org/openzal/zal/redolog/op/RedoableOp.java b/src/main/java/org/openzal/zal/redolog/op/RedoableOp.java index 0c32da5..7a47b29 100644 --- a/src/main/java/org/openzal/zal/redolog/op/RedoableOp.java +++ b/src/main/java/org/openzal/zal/redolog/op/RedoableOp.java @@ -20,26 +20,14 @@ package org.openzal.zal.redolog.op; -import com.zimbra.cs.mailbox.OperationContext; -import com.zimbra.cs.redolog.op.DataExtractor; -import java.io.DataInputStream; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.apache.commons.io.IOUtils; -import org.openzal.zal.Operation; -import org.openzal.zal.Utils; -import org.openzal.zal.extension.BootstrapClassLoader; +import org.openzal.zal.redolog.DataExtractor; import org.openzal.zal.lib.Version; -import org.openzal.zal.log.ZimbraLog; -import org.openzal.zal.redolog.*; +import org.openzal.zal.redolog.RedoLogOutput; +import org.openzal.zal.redolog.TransactionId; +import javax.annotation.Nonnull; +import java.io.DataInputStream; import java.io.IOException; -import java.lang.reflect.Method; -import org.openzal.zal.redolog.RedoLogOutput.Reader; public class RedoableOp @@ -50,23 +38,6 @@ public class RedoableOp private final com.zimbra.cs.redolog.op.RedoableOp mRedoableOp; - - @Nullable private static Method sGetVersionMethod = null; - - static - { - try - { - sGetVersionMethod = com.zimbra.cs.redolog.op.RedoableOp.class.getDeclaredMethod("getVersion"); - sGetVersionMethod.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - public RedoableOp(@Nonnull Object redoableOp) { mRedoableOp = (com.zimbra.cs.redolog.op.RedoableOp) redoableOp; @@ -96,9 +67,8 @@ public TransactionId getTransactionId() @Nonnull public Version getVersion() - throws Exception { - return Version.parse(sGetVersionMethod.invoke(mRedoableOp).toString()); + return Version.parse(mRedoableOp.getVersion().toString()); } public String toString() @@ -161,50 +131,4 @@ public void extractData(RedoLogOutput redoLogOutput) throws Exception { public org.openzal.zal.OperationContext getOperationContext() { return org.openzal.zal.OperationContext.buildFromZimbra(mRedoableOp.getOperationContext()); } - - static - { - try - { - Method defineClassMethod = ClassLoader.class.getDeclaredMethod( - "defineClass", byte[].class, int.class, int.class - ); - defineClassMethod.setAccessible(true); - - InputStream is = null; - try - { - Class parentClass = Class.forName("com.zimbra.cs.redolog.op.RedoableOp"); - ClassLoader parentClassLoader = parentClass.getClassLoader(); - - is = BootstrapClassLoader.class.getResourceAsStream("/com/zimbra/cs/redolog/op/DataExtractor"); - byte[] buffer = new byte[6 * 1024]; - int idx = 0; - int read = 0; - while (read > -1) - { - idx += read; - if (buffer.length == idx) - { - buffer = Arrays.copyOf(buffer, buffer.length * 2); - } - read = is.read(buffer, idx, buffer.length - idx); - } - - defineClassMethod.invoke( - parentClassLoader, - buffer, 0, idx - ); - } - catch (Exception ignore) {} - finally - { - IOUtils.closeQuietly(is); - } - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } } diff --git a/src/main/java/org/openzal/zal/redolog/op/RenameItem.java b/src/main/java/org/openzal/zal/redolog/op/RenameItem.java deleted file mode 100644 index 0532558..0000000 --- a/src/main/java/org/openzal/zal/redolog/op/RenameItem.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ZAL - Zextras Abstraction Layer. - * Copyright (C) 2026 ZeXtras S.r.l. - * - * This file is part of ZAL. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ZAL. If not, see . - */ - -package org.openzal.zal.redolog.op; - -import org.openzal.zal.MailItemType; - -import java.lang.reflect.Field; - -public class RenameItem { - protected int id; - protected MailItemType type; - protected int folderId; - protected String name; - protected Long date; - - public static class RenameItemInitializationException extends RuntimeException{ - public RenameItemInitializationException(Throwable cause) { - super(cause); - } - } - - public RenameItem(RedoableOp op) { - Field field; - try { - com.zimbra.cs.redolog.op.RedoableOp proxiedObject = op.getProxiedObject(); - field = com.zimbra.cs.redolog.op.RenameItem.class.getDeclaredField("mId"); - field.setAccessible(true); - id = field.getInt(proxiedObject); - - field = com.zimbra.cs.redolog.op.RenameItem.class.getDeclaredField("type"); - field.setAccessible(true); - com.zimbra.cs.mailbox.MailItem.Type type = (com.zimbra.cs.mailbox.MailItem.Type) field.get(proxiedObject); - this.type = new MailItemType(type); - - field = com.zimbra.cs.redolog.op.RenameItem.class.getDeclaredField("mFolderId"); - field.setAccessible(true); - folderId = field.getInt(proxiedObject); - - field = com.zimbra.cs.redolog.op.RenameItem.class.getDeclaredField("mName"); - field.setAccessible(true); - name = (String) field.get(proxiedObject); - - field = com.zimbra.cs.redolog.op.RenameItem.class.getDeclaredField("mDate"); - field.setAccessible(true); - date = field.getLong(proxiedObject); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RenameItemInitializationException(e); - } - - } - - public int getId() { - return id; - } - - public MailItemType getType() { - return type; - } - - public int getFolderId() { - return folderId; - } - - public String getName() { - return name; - } - - public Long getDate() { - return date; - } -} diff --git a/src/main/java/org/openzal/zal/soap/InternalAdminDocumentHandler.java b/src/main/java/org/openzal/zal/soap/InternalAdminDocumentHandler.java index b1acadb..edf801a 100644 --- a/src/main/java/org/openzal/zal/soap/InternalAdminDocumentHandler.java +++ b/src/main/java/org/openzal/zal/soap/InternalAdminDocumentHandler.java @@ -72,7 +72,7 @@ public boolean needsAuth(Map context) @Nullable @Override - protected Element proxyIfNecessary(Element request, Map context) throws ZimbraException + public Element proxyIfNecessary(Element request, Map context) throws ZimbraException { return null; } diff --git a/src/main/java/org/openzal/zal/soap/InternalOverrideAdminDocumentHandler.java b/src/main/java/org/openzal/zal/soap/InternalOverrideAdminDocumentHandler.java index afc50c3..466c434 100644 --- a/src/main/java/org/openzal/zal/soap/InternalOverrideAdminDocumentHandler.java +++ b/src/main/java/org/openzal/zal/soap/InternalOverrideAdminDocumentHandler.java @@ -20,8 +20,6 @@ package org.openzal.zal.soap; -import javax.annotation.Nullable; -import org.openzal.zal.Utils; import com.zimbra.common.service.ServiceException; import com.zimbra.common.soap.Element; import com.zimbra.cs.account.Account; @@ -31,10 +29,7 @@ import com.zimbra.soap.DocumentHandler; import com.zimbra.soap.ZimbraSoapContext; import org.openzal.zal.exceptions.ExceptionWrapper; -import org.openzal.zal.log.ZimbraLog; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Map; public class InternalOverrideAdminDocumentHandler extends AdminDocumentHandler @@ -104,44 +99,9 @@ public boolean domainAuthSufficient(Map context) return mOriginalDocumentHandler.domainAuthSufficient(context); } - @Nullable private static Method sMethod = null; - - /* - protected Element proxyIfNecessary(Element request, Map context) throws ServiceException { - */ - static + public Element proxyIfNecessary(Element request, Map context) throws ServiceException { - try - { - Class[] parameters = { - Element.class, - Map.class - }; - sMethod = DocumentHandler.class.getDeclaredMethod("proxyIfNecessary", parameters); - sMethod.setAccessible(true); - } - catch (NoSuchMethodException ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - - protected Element proxyIfNecessary(Element request, Map context) throws ServiceException - { - try - { - return (Element) sMethod.invoke(mOriginalDocumentHandler, request, context); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) - { - throw (ServiceException) e.getCause(); - } + return mOriginalDocumentHandler.proxyIfNecessary(request, context); } public boolean isAdminCommand() diff --git a/src/main/java/org/openzal/zal/soap/InternalOverrideDocumentHandler.java b/src/main/java/org/openzal/zal/soap/InternalOverrideDocumentHandler.java index 3117e4d..096a4a9 100644 --- a/src/main/java/org/openzal/zal/soap/InternalOverrideDocumentHandler.java +++ b/src/main/java/org/openzal/zal/soap/InternalOverrideDocumentHandler.java @@ -20,8 +20,6 @@ package org.openzal.zal.soap; -import javax.annotation.Nullable; -import org.openzal.zal.Utils; import com.zimbra.common.service.ServiceException; import com.zimbra.common.soap.Element; import com.zimbra.cs.account.Account; @@ -30,10 +28,7 @@ import com.zimbra.soap.DocumentHandler; import com.zimbra.soap.ZimbraSoapContext; import org.openzal.zal.exceptions.ExceptionWrapper; -import org.openzal.zal.log.ZimbraLog; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Map; public class InternalOverrideDocumentHandler extends DocumentHandler @@ -113,44 +108,10 @@ public boolean isReadOnly() return mOriginalDocumentHandler.isReadOnly(); } - @Nullable private static Method sMethod = null; - /* - protected Element proxyIfNecessary(Element request, Map context) throws ServiceException { - */ - static + public Element proxyIfNecessary(Element request, Map context) throws ServiceException { - try - { - Class[] parameters = { - Element.class, - Map.class - }; - sMethod = DocumentHandler.class.getDeclaredMethod("proxyIfNecessary", parameters); - sMethod.setAccessible(true); - } - catch (NoSuchMethodException ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - - - protected Element proxyIfNecessary(Element request, Map context) throws ServiceException - { - try - { - return (Element) sMethod.invoke(mOriginalDocumentHandler, request, context); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) - { - throw (ServiceException) e.getCause(); - } + return mOriginalDocumentHandler.proxyIfNecessary(request, context); } public void preProxy(Element request, Map context) throws ServiceException diff --git a/src/main/java/org/openzal/zal/soap/SoapServiceManager.java b/src/main/java/org/openzal/zal/soap/SoapServiceManager.java index ab285bc..ab0b243 100644 --- a/src/main/java/org/openzal/zal/soap/SoapServiceManager.java +++ b/src/main/java/org/openzal/zal/soap/SoapServiceManager.java @@ -20,29 +20,23 @@ package org.openzal.zal.soap; -import com.google.common.cache.LoadingCache; -import com.zimbra.soap.*; +import com.zimbra.soap.DocumentHandler; +import com.zimbra.soap.SoapServlet; import org.dom4j.QName; import org.openzal.zal.Utils; -import org.openzal.zal.lib.ZimbraVersion; import org.openzal.zal.log.ZimbraLog; -import java.lang.reflect.Field; -import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class SoapServiceManager { private final static Map sOriginalHandlersMap; - private static Field sExtraServices; static { try { - sExtraServices = com.zimbra.soap.SoapServlet.class.getDeclaredField("sExtraServices"); - sExtraServices.setAccessible(true); sOriginalHandlersMap = new ConcurrentHashMap(64); } catch (Throwable ex) @@ -84,18 +78,7 @@ public void unregister(SoapService soapService) soapService.getServiceName(), new InternalUnregisterDocumentService(soapService) ); - - try - { - synchronized(this) - { - ((LoadingCache>) sExtraServices.get(null)).invalidate(soapService.getServiceName()); - } - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } + SoapServlet.invalidateServiceCache(soapService.getServiceName()); } public void overrideZimbraHandler(OverridenSoapService soapService) diff --git a/src/main/java/org/openzal/zal/soap/ZimbraContextImpl.java b/src/main/java/org/openzal/zal/soap/ZimbraContextImpl.java index 74ad100..0a79b10 100644 --- a/src/main/java/org/openzal/zal/soap/ZimbraContextImpl.java +++ b/src/main/java/org/openzal/zal/soap/ZimbraContextImpl.java @@ -24,16 +24,12 @@ import javax.annotation.Nullable; import org.openzal.zal.Continuation; import org.openzal.zal.Jetty; -import org.openzal.zal.Utils; import com.zimbra.common.soap.Element; import com.zimbra.soap.SoapEngine; import com.zimbra.soap.SoapServlet; import com.zimbra.soap.ZimbraSoapContext; -import org.openzal.zal.log.ZimbraLog; import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -225,47 +221,12 @@ public String getRequesterIp() return (ip != null) ? ip.toString() : ""; } - private static Method sDispatchRequest = null; - - /* Element dispatchRequest(Element request, Map context, ZimbraSoapContext zsc); */ - static - { - try - { - Class partypes[] = { - Element.class, - Map.class, - ZimbraSoapContext.class - }; - - sDispatchRequest = SoapEngine.class.getDeclaredMethod("dispatchRequest", partypes); - sDispatchRequest.setAccessible(true); - } - catch (Throwable ex) - { - ZimbraLog.extensions.fatal("ZAL Reflection Initialization Exception: " + Utils.exceptionToString(ex)); - throw new RuntimeException(ex); - } - } - @Override public SoapResponse execLocalRequest() { SoapEngine soapEngine = (SoapEngine) mContext.get(SoapEngine.ZIMBRA_ENGINE); ZimbraSoapContext zimbraSoapContext = (ZimbraSoapContext) mContext.get(SoapEngine.ZIMBRA_CONTEXT); - try - { - Element response = (Element)sDispatchRequest.invoke(soapEngine, mRequest, mContext, mZimbraSoapContext ); - return new SoapResponseImpl(response, new InternalDocumentHelper.ElementFactory(zimbraSoapContext)); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) - { - throw new RuntimeException(e.getCause()); - } + return new SoapResponseImpl(soapEngine.dispatchRequest(mRequest, mContext, mZimbraSoapContext), new InternalDocumentHelper.ElementFactory(zimbraSoapContext)); } @Override diff --git a/src/test/java/org/openzal/zal/extension/ZimbraIT.java b/src/test/java/org/openzal/zal/extension/ZimbraIT.java index 1a4ad4f..f86370c 100644 --- a/src/test/java/org/openzal/zal/extension/ZimbraIT.java +++ b/src/test/java/org/openzal/zal/extension/ZimbraIT.java @@ -1,16 +1,9 @@ package org.openzal.zal.extension; -import org.openzal.zal.mailbox.ZalZimbraSimulator; import org.junit.Rule; import org.junit.Test; -import org.openzal.zal.lib.PermissiveMap; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import org.openzal.zal.mailbox.ZalZimbraSimulator; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; public class ZimbraIT @@ -30,27 +23,4 @@ public void remove_extension() Zimbra zimbra = mZimbraSimulator.getZimbra(); assertFalse(zimbra.removeExtension("not_existing_extension")); } - - @Test - public void removing_extension_should_not_throw_concurrent_modification_exception() - { - Map map = new PermissiveMap(); - - map.put("A","A"); - map.put("B","B"); - map.put("C","C"); - - List result = new LinkedList(); - - for( String val : map.values() ) - { - result.add(val); - map.remove("B"); - } - - assertEquals( - Arrays.asList("A","C"), - result - ); - } } \ No newline at end of file diff --git a/src/test/java/org/openzal/zal/index/IndexerProxyMapIT.java b/src/test/java/org/openzal/zal/index/IndexerProxyMapIT.java index 125386e..a84cef5 100644 --- a/src/test/java/org/openzal/zal/index/IndexerProxyMapIT.java +++ b/src/test/java/org/openzal/zal/index/IndexerProxyMapIT.java @@ -1,6 +1,6 @@ package org.openzal.zal.index; -import com.zimbra.cs.mime.MimeHandler; +import com.zimbra.cs.mime.MimeHandlerManager; import org.junit.Before; import org.junit.Test; @@ -11,19 +11,18 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - public class IndexerProxyMapIT { private IndexerProxyMap mIndexerProxyMap; - private HashMap mMap; + private HashMap mMap; private MimeHandlerProvider mMimeHandlerProvider; - private MimeHandler mMimeHandler1; - private MimeHandler mMimeHandler2; + private MimeHandlerManager.HandlerInfo mMimeHandler1; + private MimeHandlerManager.HandlerInfo mMimeHandler2; @Before public void setup() { - mMimeHandler1 = mock(MimeHandler.class); - mMimeHandler2 = mock(MimeHandler.class); - mMap = new HashMap(); + mMimeHandler1 = mock(MimeHandlerManager.HandlerInfo.class); + mMimeHandler2 = mock(MimeHandlerManager.HandlerInfo.class); + mMap = new HashMap(); mMimeHandlerProvider = mock(MimeHandlerProvider.class); mIndexerProxyMap = new IndexerProxyMap( mMap, diff --git a/src/test/java/org/openzal/zal/lib/PermissiveMapIT.java b/src/test/java/org/openzal/zal/lib/PermissiveMapIT.java deleted file mode 100644 index 6142413..0000000 --- a/src/test/java/org/openzal/zal/lib/PermissiveMapIT.java +++ /dev/null @@ -1,1547 +0,0 @@ -package org.openzal.zal.lib; - -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import static java.util.Collections.singleton; -import static org.junit.Assert.*; - -/* - Copied from google guice testing (MapInterfaceTest.java). - Converted from to for the sake of simplicity. - No particular customizations were made. -*/ - -public class PermissiveMapIT -{ - protected final boolean supportsPut = true; - protected final boolean supportsRemove = true; - protected final boolean supportsClear = true; - protected final boolean allowsNullKeys = true; - protected final boolean allowsNullValues = true; - protected final boolean supportsIteratorRemove = true; - - /** - * Creates a new, empty instance of the class under test. - * - * @return a new, empty map instance. - * @throws UnsupportedOperationException if it's not possible to make an - * empty instance of the class under test. - */ - protected Map makeEmptyMap() - throws UnsupportedOperationException - { - return new PermissiveMap(); - } - - /** - * Creates a new, non-empty instance of the class under test. - * - * @return a new, non-empty map instance. - * @throws UnsupportedOperationException if it's not possible to make a - * non-empty instance of the class under test. - */ - protected Map makePopulatedMap() - throws UnsupportedOperationException - { - PermissiveMap map = new PermissiveMap(); - map.put("key","value"); - return map; - } - - /** - * Creates a new key that is not expected to be found - * in {@link #makePopulatedMap()}. - * - * @return a key. - * @throws UnsupportedOperationException if it's not possible to make a key - * that will not be found in the map. - */ - protected String getKeyNotInPopulatedMap() - throws UnsupportedOperationException - { - return "YouCantFindMe"; - } - - /** - * Creates a new value that is not expected to be found - * in {@link #makePopulatedMap()}. - * - * @return a value. - * @throws UnsupportedOperationException if it's not possible to make a value - * that will not be found in the map. - */ - protected String getValueNotInPopulatedMap() - throws UnsupportedOperationException - { - return "YouWontFindMe"; - } - - - /** - * Used by tests that require a map, but don't care whether it's - * populated or not. - * - * @return a new map instance. - */ - protected Map makeEitherMap() { - try { - return makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return makeEmptyMap(); - } - } - - protected final boolean supportsValuesHashCode(Map map) { - // get the first non-null value - Collection values = map.values(); - for (String value : values) { - if (value != null) { - try { - value.hashCode(); - } catch (Exception e) { - return false; - } - return true; - } - } - return true; - } - - /** - * Checks all the properties that should always hold of a map. Also calls - * {@link #assertMoreInvariants} to check invariants that are peculiar to - * specific implementations. - * - * @see #assertMoreInvariants - * @param map the map to check. - */ - protected final void assertInvariants(Map map) { - Set keySet = map.keySet(); - Collection valueCollection = map.values(); - Set> entrySet = map.entrySet(); - - assertEquals(map.size() == 0, map.isEmpty()); - assertEquals(map.size(), keySet.size()); - assertEquals(keySet.size() == 0, keySet.isEmpty()); - assertEquals(!keySet.isEmpty(), keySet.iterator().hasNext()); - - int expectedKeySetHash = 0; - for (String key : keySet) { - String value = map.get(key); - expectedKeySetHash += key != null ? key.hashCode() : 0; - assertTrue(map.containsKey(key)); - assertTrue(map.containsValue(value)); - assertTrue(valueCollection.contains(value)); - assertTrue(valueCollection.containsAll(singleton(value))); - assertTrue(entrySet.contains(mapEntry(key, value))); - assertTrue(allowsNullKeys || (key != null)); - } - assertEquals(expectedKeySetHash, keySet.hashCode()); - - assertEquals(map.size(), valueCollection.size()); - assertEquals(valueCollection.size() == 0, valueCollection.isEmpty()); - assertEquals( - !valueCollection.isEmpty(), valueCollection.iterator().hasNext()); - for (String value : valueCollection) { - assertTrue(map.containsValue(value)); - assertTrue(allowsNullValues || (value != null)); - } - - assertEquals(map.size(), entrySet.size()); - assertEquals(entrySet.size() == 0, entrySet.isEmpty()); - assertEquals(!entrySet.isEmpty(), entrySet.iterator().hasNext()); - assertFalse(entrySet.contains("foo")); - - boolean supportsValuesHashCode = supportsValuesHashCode(map); - if (supportsValuesHashCode) { - int expectedEntrySetHash = 0; - for (Map.Entry entry : entrySet) { - assertTrue(map.containsKey(entry.getKey())); - assertTrue(map.containsValue(entry.getValue())); - int expectedHash = - (entry.getKey() == null ? 0 : entry.getKey().hashCode()) ^ - (entry.getValue() == null ? 0 : entry.getValue().hashCode()); - assertEquals(expectedHash, entry.hashCode()); - expectedEntrySetHash += expectedHash; - } - assertEquals(expectedEntrySetHash, entrySet.hashCode()); - assertTrue(entrySet.containsAll(new HashSet>(entrySet))); - assertTrue(entrySet.equals(new HashSet>(entrySet))); - } - - Object[] entrySetToArray1 = entrySet.toArray(); - assertEquals(map.size(), entrySetToArray1.length); - assertTrue(Arrays.asList(entrySetToArray1).containsAll(entrySet)); - - Map.Entry[] entrySetToArray2 = new Map.Entry[map.size() + 2]; - entrySetToArray2[map.size()] = mapEntry("foo", "1"); - assertSame(entrySetToArray2, entrySet.toArray(entrySetToArray2)); - assertNull(entrySetToArray2[map.size()]); - assertTrue(Arrays.asList(entrySetToArray2).containsAll(entrySet)); - - Object[] valuesToArray1 = valueCollection.toArray(); - assertEquals(map.size(), valuesToArray1.length); - assertTrue(Arrays.asList(valuesToArray1).containsAll(valueCollection)); - - Object[] valuesToArray2 = new Object[map.size() + 2]; - valuesToArray2[map.size()] = "foo"; - assertSame(valuesToArray2, valueCollection.toArray(valuesToArray2)); - assertNull(valuesToArray2[map.size()]); - assertTrue(Arrays.asList(valuesToArray2).containsAll(valueCollection)); - - if (supportsValuesHashCode) { - int expectedHash = 0; - for (Map.Entry entry : entrySet) { - expectedHash += entry.hashCode(); - } - assertEquals(expectedHash, map.hashCode()); - } - - assertMoreInvariants(map); - } - - /** - * Override this to check invariants which should hold true for a particular - * implementation, but which are not generally applicable to every instance - * of Map. - * - * @param map the map whose additional invariants to check. - */ - protected void assertMoreInvariants(Map map) { - } - - @Test - public void testClear() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - if (supportsClear) { - map.clear(); - assertTrue(map.isEmpty()); - } else { - try { - map.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testContainsKey() { - final Map map; - final String unmappedKey; - try { - map = makePopulatedMap(); - unmappedKey = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertFalse(map.containsKey(unmappedKey)); - assertTrue(map.containsKey(map.keySet().iterator().next())); - if (allowsNullKeys) { - map.containsKey(null); - } else { - try { - map.containsKey(null); - } catch (NullPointerException optional) { - } - } - assertInvariants(map); - } - - @Test - public void testContainsValue() { - final Map map; - final String unmappedValue; - try { - map = makePopulatedMap(); - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertFalse(map.containsValue(unmappedValue)); - assertTrue(map.containsValue(map.values().iterator().next())); - if (allowsNullValues) { - map.containsValue(null); - } else { - try { - map.containsKey(null); - } catch (NullPointerException optional) { - } - } - assertInvariants(map); - } - - @Test - public void testEntrySet() { - final Map map; - final Set> entrySet; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final String unmappedKey; - final String unmappedValue; - try { - unmappedKey = getKeyNotInPopulatedMap(); - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - for (Map.Entry entry : entrySet) { - assertFalse(unmappedKey.equals(entry.getKey())); - assertFalse(unmappedValue.equals(entry.getValue())); - } - } - - @Test - public void testEntrySetForEmptyMap() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - } - - @Test - public void testEntrySetContainsEntryNullKeyPresent() { - if (!allowsNullKeys || !supportsPut) { - return; - } - final Map map; - final Set> entrySet; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final String unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - map.put(null, unmappedValue); - Map.Entry entry = mapEntry(null, unmappedValue); - assertTrue(entrySet.contains(entry)); - assertFalse(entrySet.contains(mapEntry(null, null))); - } - - @Test - public void testEntrySetContainsEntryNullKeyMissing() { - final Map map; - final Set> entrySet; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final String unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Map.Entry entry = mapEntry(null, unmappedValue); - assertFalse(entrySet.contains(entry)); - assertFalse(entrySet.contains(mapEntry(null, null))); - } - - @Test - public void testEntrySetIteratorRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Iterator> iterator = entrySet.iterator(); - if (supportsIteratorRemove) { - int initialSize = map.size(); - Map.Entry entry = iterator.next(); - iterator.remove(); - assertEquals(initialSize - 1, map.size()); - assertFalse(entrySet.contains(entry)); - assertInvariants(map); - try { - iterator.remove(); - fail("Expected IllegalStateException."); - } catch (IllegalStateException e) { - // Expected. - } - } else { - try { - iterator.next(); - iterator.remove(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsRemove) { - int initialSize = map.size(); - boolean didRemove = entrySet.remove(entrySet.iterator().next()); - assertTrue(didRemove); - assertEquals(initialSize - 1, map.size()); - } else { - try { - entrySet.remove(entrySet.iterator().next()); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetRemoveMissingKey() { - final Map map; - final String key; - try { - map = makeEitherMap(); - key = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Map.Entry entry - = mapEntry(key, getValueNotInPopulatedMap()); - int initialSize = map.size(); - if (supportsRemove) { - boolean didRemove = entrySet.remove(entry); - assertFalse(didRemove); - } else { - try { - boolean didRemove = entrySet.remove(entry); - assertFalse(didRemove); - } catch (UnsupportedOperationException optional) {} - } - assertEquals(initialSize, map.size()); - assertFalse(map.containsKey(key)); - assertInvariants(map); - } - - @Test - public void testEntrySetRemoveDifferentValue() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - String key = map.keySet().iterator().next(); - Map.Entry entry - = mapEntry(key, getValueNotInPopulatedMap()); - int initialSize = map.size(); - if (supportsRemove) { - boolean didRemove = entrySet.remove(entry); - assertFalse(didRemove); - } else { - try { - boolean didRemove = entrySet.remove(entry); - assertFalse(didRemove); - } catch (UnsupportedOperationException optional) {} - } - assertEquals(initialSize, map.size()); - assertTrue(map.containsKey(key)); - assertInvariants(map); - } - - @Test - public void testEntrySetRemoveNullKeyPresent() { - if (!allowsNullKeys || !supportsPut || !supportsRemove) { - return; - } - final Map map; - final Set> entrySet; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final String unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - map.put(null, unmappedValue); - assertEquals(unmappedValue, map.get(null)); - assertTrue(map.containsKey(null)); - Map.Entry entry = mapEntry(null, unmappedValue); - assertTrue(entrySet.remove(entry)); - assertNull(map.get(null)); - assertFalse(map.containsKey(null)); - } - - @Test - public void testEntrySetRemoveNullKeyMissing() { - final Map map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Map.Entry entry - = mapEntry(null, getValueNotInPopulatedMap()); - int initialSize = map.size(); - if (supportsRemove) { - boolean didRemove = entrySet.remove(entry); - assertFalse(didRemove); - } else { - try { - boolean didRemove = entrySet.remove(entry); - assertFalse(didRemove); - } catch (UnsupportedOperationException optional) {} - } - assertEquals(initialSize, map.size()); - assertInvariants(map); - } - - @Test - public void testEntrySetRemoveAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Set> entriesToRemove = - singleton(entrySet.iterator().next()); - if (supportsRemove) { - int initialSize = map.size(); - boolean didRemove = entrySet.removeAll(entriesToRemove); - assertTrue(didRemove); - assertEquals(initialSize - entriesToRemove.size(), map.size()); - for (Map.Entry entry : entriesToRemove) { - assertFalse(entrySet.contains(entry)); - } - } else { - try { - entrySet.removeAll(entriesToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetRemoveAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsRemove) { - try { - entrySet.removeAll(null); - fail("Expected NullPointerException."); - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - entrySet.removeAll(null); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetRetainAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Set> entriesToRetain = - singleton(entrySet.iterator().next()); - if (supportsRemove) { - boolean shouldRemove = (entrySet.size() > entriesToRetain.size()); - boolean didRemove = entrySet.retainAll(entriesToRetain); - assertEquals(shouldRemove, didRemove); - assertEquals(entriesToRetain.size(), map.size()); - for (Map.Entry entry : entriesToRetain) { - assertTrue(entrySet.contains(entry)); - } - } else { - try { - entrySet.retainAll(entriesToRetain); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetRetainAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsRemove) { - try { - entrySet.retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - entrySet.retainAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetClear() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsClear) { - entrySet.clear(); - assertTrue(entrySet.isEmpty()); - } else { - try { - entrySet.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testEntrySetAddAndAddAll() { - final Map map = makeEitherMap(); - - Set> entrySet = map.entrySet(); - final Map.Entry entryToAdd = mapEntry(null, null); - try { - entrySet.add(entryToAdd); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - assertInvariants(map); - - try { - entrySet.addAll(singleton(entryToAdd)); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - assertInvariants(map); - } - - @Test - public void testEntrySetSetValue() { - // TODO: Investigate the extent to which, in practice, maps that support - // put() also support Entry.setValue(). - if (!supportsPut) { - return; - } - - final Map map; - final String valueToSet; - try { - map = makePopulatedMap(); - valueToSet = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Map.Entry entry = entrySet.iterator().next(); - final String oldValue = entry.getValue(); - final String returnedValue = entry.setValue(valueToSet); - assertEquals(oldValue, returnedValue); - assertTrue(entrySet.contains( - mapEntry(entry.getKey(), valueToSet))); - assertEquals(valueToSet, map.get(entry.getKey())); - assertInvariants(map); - } - - @Test - public void testEntrySetSetValueSameValue() { - // TODO: Investigate the extent to which, in practice, maps that support - // put() also support Entry.setValue(). - if (!supportsPut) { - return; - } - - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Map.Entry entry = entrySet.iterator().next(); - final String oldValue = entry.getValue(); - final String returnedValue = entry.setValue(oldValue); - assertEquals(oldValue, returnedValue); - assertTrue(entrySet.contains( - mapEntry(entry.getKey(), oldValue))); - assertEquals(oldValue, map.get(entry.getKey())); - assertInvariants(map); - } - - @Test - public void testEqualsForEqualMap() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - assertEquals(map, map); - assertEquals(makePopulatedMap(), map); - assertFalse(map.equals(Collections.emptyMap())); - //no-inspection ObjectEqualsNull - assertFalse(map.equals(null)); - } - - @Test - public void testEqualsForLargerMap() { - if (!supportsPut) { - return; - } - - final Map map; - final Map largerMap; - try { - map = makePopulatedMap(); - largerMap = makePopulatedMap(); - largerMap.put(getKeyNotInPopulatedMap(), getValueNotInPopulatedMap()); - } catch (UnsupportedOperationException e) { - return; - } - - assertFalse(map.equals(largerMap)); - } - - @Test - public void testEqualsForSmallerMap() { - if (!supportsRemove) { - return; - } - - final Map map; - final Map smallerMap; - try { - map = makePopulatedMap(); - smallerMap = makePopulatedMap(); - smallerMap.remove(smallerMap.keySet().iterator().next()); - } catch (UnsupportedOperationException e) { - return; - } - - assertFalse(map.equals(smallerMap)); - } - - @Test - public void testEqualsForEmptyMap() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - assertEquals(map, map); - assertEquals(makeEmptyMap(), map); - assertEquals(Collections.emptyMap(), map); - assertFalse(map.equals(Collections.emptySet())); - //noinspection ObjectEqualsNull - assertFalse(map.equals(null)); - } - - @Test - public void testGet() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - for (Map.Entry entry : map.entrySet()) { - assertEquals(entry.getValue(), map.get(entry.getKey())); - } - - String unmappedKey = null; - try { - unmappedKey = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertNull(map.get(unmappedKey)); - } - - @Test - public void testGetForEmptyMap() { - final Map map; - String unmappedKey = null; - try { - map = makeEmptyMap(); - unmappedKey = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertNull(map.get(unmappedKey)); - } - - @Test - public void testGetNull() { - Map map = makeEitherMap(); - if (allowsNullKeys) { - if (allowsNullValues) { - // TODO: decide what to test here. - } else { - assertEquals(map.containsKey(null), map.get(null) != null); - } - } else { - try { - map.get(null); - } catch (NullPointerException optional) { - } - } - assertInvariants(map); - } - - @Test - public void testHashCode() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - } - - @Test - public void testHashCodeForEmptyMap() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - } - - @Test - public void testPutNewKey() { - final Map map = makeEitherMap(); - final String keyToPut; - final String valueToPut; - try { - keyToPut = getKeyNotInPopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (supportsPut) { - int initialSize = map.size(); - String oldValue = map.put(keyToPut, valueToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize + 1, map.size()); - assertNull(oldValue); - } else { - try { - map.put(keyToPut, valueToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testPutExistingKey() { - final Map map; - final String keyToPut; - final String valueToPut; - try { - map = makePopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - keyToPut = map.keySet().iterator().next(); - if (supportsPut) { - int initialSize = map.size(); - map.put(keyToPut, valueToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize, map.size()); - } else { - try { - map.put(keyToPut, valueToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testPutNullKey() { - if (!supportsPut) { - return; - } - final Map map = makeEitherMap(); - final String valueToPut; - try { - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (allowsNullKeys) { - final String oldValue = map.get(null); - final String returnedValue = map.put(null, valueToPut); - assertEquals(oldValue, returnedValue); - assertEquals(valueToPut, map.get(null)); - assertTrue(map.containsKey(null)); - assertTrue(map.containsValue(valueToPut)); - } else { - try { - map.put(null, valueToPut); - fail("Expected RuntimeException"); - } catch (RuntimeException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testPutNullValue() { - if (!supportsPut) { - return; - } - final Map map = makeEitherMap(); - final String keyToPut; - try { - keyToPut = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (allowsNullValues) { - int initialSize = map.size(); - final String oldValue = map.get(keyToPut); - final String returnedValue = map.put(keyToPut, null); - assertEquals(oldValue, returnedValue); - assertNull(map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(null)); - assertEquals(initialSize + 1, map.size()); - } else { - try { - map.put(keyToPut, null); - fail("Expected RuntimeException"); - } catch (RuntimeException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testPutNullValueForExistingKey() { - if (!supportsPut) { - return; - } - final Map map; - final String keyToPut; - try { - map = makePopulatedMap(); - keyToPut = map.keySet().iterator().next(); - } catch (UnsupportedOperationException e) { - return; - } - if (allowsNullValues) { - int initialSize = map.size(); - final String oldValue = map.get(keyToPut); - final String returnedValue = map.put(keyToPut, null); - assertEquals(oldValue, returnedValue); - assertNull(map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(null)); - assertEquals(initialSize, map.size()); - } else { - try { - map.put(keyToPut, null); - fail("Expected RuntimeException"); - } catch (RuntimeException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testPutAllNewKey() { - final Map map = makeEitherMap(); - final String keyToPut; - final String valueToPut; - try { - keyToPut = getKeyNotInPopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); - if (supportsPut) { - int initialSize = map.size(); - map.putAll(mapToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize + 1, map.size()); - } else { - try { - map.putAll(mapToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testPutAllExistingKey() { - final Map map; - final String keyToPut; - final String valueToPut; - try { - map = makePopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - keyToPut = map.keySet().iterator().next(); - final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); - int initialSize = map.size(); - if (supportsPut) { - map.putAll(mapToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - } else { - try { - map.putAll(mapToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertEquals(initialSize, map.size()); - assertInvariants(map); - } - - @Test - public void testRemove() { - final Map map; - final String keyToRemove; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - keyToRemove = map.keySet().iterator().next(); - if (supportsRemove) { - int initialSize = map.size(); - String expectedValue = map.get(keyToRemove); - String oldValue = map.remove(keyToRemove); - assertEquals(expectedValue, oldValue); - assertFalse(map.containsKey(keyToRemove)); - assertEquals(initialSize - 1, map.size()); - } else { - try { - map.remove(keyToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testRemoveMissingKey() { - final Map map; - final String keyToRemove; - try { - map = makePopulatedMap(); - keyToRemove = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (supportsRemove) { - int initialSize = map.size(); - assertNull(map.remove(keyToRemove)); - assertEquals(initialSize, map.size()); - } else { - try { - map.remove(keyToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testSize() { - assertInvariants(makeEitherMap()); - } - - @Test - public void testKeySetClear() { - final Map map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set keySet = map.keySet(); - if (supportsClear) { - keySet.clear(); - assertTrue(keySet.isEmpty()); - } else { - try { - keySet.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testKeySetRemoveAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set keySet = map.keySet(); - if (supportsRemove) { - try { - keySet.removeAll(null); - fail("Expected NullPointerException."); - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - keySet.removeAll(null); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testKeySetRetainAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set keySet = map.keySet(); - if (supportsRemove) { - try { - keySet.retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - keySet.retainAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValues() { - final Map map; - final Collection valueCollection; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - valueCollection = map.values(); - final String unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - for (String value : valueCollection) { - assertFalse(unmappedValue.equals(value)); - } - } - - @Test - public void testValuesIteratorRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - Iterator iterator = valueCollection.iterator(); - if (supportsIteratorRemove) { - int initialSize = map.size(); - iterator.next(); - iterator.remove(); - assertEquals(initialSize - 1, map.size()); - // (We can't assert that the values collection no longer contains the - // removed value, because the underlying map can have multiple mappings - // to the same value.) - assertInvariants(map); - try { - iterator.remove(); - fail("Expected IllegalStateException."); - } catch (IllegalStateException e) { - // Expected. - } - } else { - try { - iterator.next(); - iterator.remove(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValuesRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - if (supportsRemove) { - int initialSize = map.size(); - valueCollection.remove(valueCollection.iterator().next()); - assertEquals(initialSize - 1, map.size()); - // (We can't assert that the values collection no longer contains the - // removed value, because the underlying map can have multiple mappings - // to the same value.) - } else { - try { - valueCollection.remove(valueCollection.iterator().next()); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValuesRemoveMissing() { - final Map map; - final String valueToRemove; - try { - map = makeEitherMap(); - valueToRemove = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - int initialSize = map.size(); - if (supportsRemove) { - assertFalse(valueCollection.remove(valueToRemove)); - } else { - try { - assertFalse(valueCollection.remove(valueToRemove)); - } catch (UnsupportedOperationException e) { - // Tolerated. - } - } - assertEquals(initialSize, map.size()); - assertInvariants(map); - } - - @Test - public void testValuesRemoveAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - Set valuesToRemove = singleton(valueCollection.iterator().next()); - if (supportsRemove) { - valueCollection.removeAll(valuesToRemove); - for (String value : valuesToRemove) { - assertFalse(valueCollection.contains(value)); - } - for (String value : valueCollection) { - assertFalse(valuesToRemove.contains(value)); - } - } else { - try { - valueCollection.removeAll(valuesToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValuesRemoveAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection values = map.values(); - if (supportsRemove) { - try { - values.removeAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - values.removeAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValuesRetainAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - Set valuesToRetain = singleton(valueCollection.iterator().next()); - if (supportsRemove) { - valueCollection.retainAll(valuesToRetain); - for (String value : valuesToRetain) { - assertTrue(valueCollection.contains(value)); - } - for (String value : valueCollection) { - assertTrue(valuesToRetain.contains(value)); - } - } else { - try { - valueCollection.retainAll(valuesToRetain); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValuesRetainAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection values = map.values(); - if (supportsRemove) { - try { - values.retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - values.retainAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - @Test - public void testValuesClear() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - if (supportsClear) { - valueCollection.clear(); - assertTrue(valueCollection.isEmpty()); - } else { - try { - valueCollection.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - private static Map.Entry mapEntry(String key, String value) { - return Collections.singletonMap(key, value).entrySet().iterator().next(); - } -} \ No newline at end of file