microsoft.exchange.webservices.data.misc.UserConfiguration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ews-java-api Show documentation
Show all versions of ews-java-api Show documentation
Exchange Web Services (EWS) Java API
/*
* The MIT License
* Copyright (c) 2012 Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package microsoft.exchange.webservices.data.misc;
import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
import microsoft.exchange.webservices.data.core.EwsUtilities;
import microsoft.exchange.webservices.data.core.ExchangeService;
import microsoft.exchange.webservices.data.core.XmlAttributeNames;
import microsoft.exchange.webservices.data.core.XmlElementNames;
import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
import microsoft.exchange.webservices.data.core.enumeration.misc.UserConfigurationProperties;
import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName;
import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
import microsoft.exchange.webservices.data.core.exception.misc.InvalidOperationException;
import microsoft.exchange.webservices.data.core.exception.service.local.PropertyException;
import microsoft.exchange.webservices.data.core.exception.service.local.ServiceVersionException;
import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
import microsoft.exchange.webservices.data.property.complex.FolderId;
import microsoft.exchange.webservices.data.property.complex.ItemId;
import microsoft.exchange.webservices.data.property.complex.UserConfigurationDictionary;
import microsoft.exchange.webservices.data.security.XmlNodeType;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.stream.XMLStreamException;
import java.util.EnumSet;
/**
* Represents an object that can be used to store user-defined configuration
* settings.
*/
public class UserConfiguration {
private static final Log LOG = LogFactory.getLog(UserConfiguration.class);
/**
* The object version.
*/
private static ExchangeVersion ObjectVersion = ExchangeVersion.Exchange2010;
/**
* For consistency with ServiceObject behavior, access to ItemId is
* permitted for a new object.
*/
/**
* The Constant PropertiesAvailableForNewObject.
*/
private final static EnumSet
PropertiesAvailableForNewObject =
EnumSet.of(UserConfigurationProperties.BinaryData,
UserConfigurationProperties.Dictionary,
UserConfigurationProperties.XmlData);
/**
* The No property.
*/
private final UserConfigurationProperties NoProperties =
UserConfigurationProperties.values()[0];
/**
* The service.
*/
private ExchangeService service;
/**
* The name.
*/
private String name;
/**
* The parent folder id.
*/
private FolderId parentFolderId = null;
/**
* The item id.
*/
private ItemId itemId = null;
/**
* The dictionary.
*/
private UserConfigurationDictionary dictionary = null;
/**
* The xml data.
*/
private byte[] xmlData = null;
/**
* The binary data.
*/
private byte[] binaryData = null;
/**
* The property available for access.
*/
private EnumSet propertiesAvailableForAccess;
/**
* The updated property.
*/
private EnumSet updatedProperties;
/**
* Indicates whether changes trigger an update or create operation.
*/
private boolean isNew = false;
/**
* Initializes a new instance of {@link UserConfiguration} class.
*
* @param service The service to which the user configuration is bound.
* @throws Exception the exception
*/
public UserConfiguration(ExchangeService service) throws Exception {
this(service, PropertiesAvailableForNewObject);
}
/**
* Writes a byte array to Xml.
*
* @param writer the writer
* @param byteArray byte array to write
* @param xmlElementName name of the Xml element
* @throws XMLStreamException the XML stream exception
* @throws ServiceXmlSerializationException the service xml serialization exception
*/
private static void writeByteArrayToXml(EwsServiceXmlWriter writer,
byte[] byteArray, String xmlElementName) throws XMLStreamException, ServiceXmlSerializationException {
EwsUtilities.ewsAssert(writer != null, "UserConfiguration.WriteByteArrayToXml", "writer is null");
EwsUtilities.ewsAssert(xmlElementName != null, "UserConfiguration.WriteByteArrayToXml",
"xmlElementName is null");
writer.writeStartElement(XmlNamespace.Types, xmlElementName);
if (byteArray != null && byteArray.length > 0) {
writer.writeValue(Base64.encodeBase64String(byteArray), xmlElementName);
}
writer.writeEndElement();
}
/**
* Writes to Xml.
*
* @param writer The writer.
* @param xmlNamespace The XML namespace.
* @param name The user configuration name.
* @param parentFolderId The Id of the folder containing the user configuration.
* @throws Exception the exception
*/
public static void writeUserConfigurationNameToXml(EwsServiceXmlWriter writer, XmlNamespace xmlNamespace,
String name, FolderId parentFolderId) throws Exception {
EwsUtilities.ewsAssert(writer != null, "UserConfiguration.WriteUserConfigurationNameToXml",
"writer is null");
EwsUtilities.ewsAssert(name != null, "UserConfiguration.WriteUserConfigurationNameToXml", "name is null");
EwsUtilities.ewsAssert(parentFolderId != null, "UserConfiguration.WriteUserConfigurationNameToXml",
"parentFolderId is null");
writer.writeStartElement(xmlNamespace,
XmlElementNames.UserConfigurationName);
writer.writeAttributeValue(XmlAttributeNames.Name, name);
parentFolderId.writeToXml(writer);
writer.writeEndElement();
}
/**
* Initializes a new instance of {@link UserConfiguration} class.
*
* @param service The service to which the user configuration is bound.
* @param requestedProperties The property requested for this user configuration.
* @throws Exception the exception
*/
public UserConfiguration(ExchangeService service, EnumSet requestedProperties)
throws Exception {
EwsUtilities.validateParam(service, "service");
if (service.getRequestedServerVersion().ordinal() < UserConfiguration.ObjectVersion.ordinal()) {
throw new ServiceVersionException(String.format(
"The object type %s is only valid for Exchange Server version %s or later versions.", this
.getClass().getName(), UserConfiguration.ObjectVersion));
}
this.service = service;
this.isNew = true;
this.initializeProperties(requestedProperties);
}
/**
* Gets the name of the user configuration.
*
* @return the name
*/
public String getName() {
return this.name;
}
/**
* Sets the name.
*
* @param value the new name
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the Id of the folder containing the user configuration.
*
* @return the parent folder id
*/
public FolderId getParentFolderId() {
return this.parentFolderId;
}
/**
* Sets the parent folder id.
*
* @param value the new parent folder id
*/
public void setParentFolderId(FolderId value) {
this.parentFolderId = value;
}
/**
* Gets the Id of the user configuration.
*
* @return the item id
*/
public ItemId getItemId() {
return this.itemId;
}
/**
* Gets the dictionary of the user configuration.
*
* @return the dictionary
*/
public UserConfigurationDictionary getDictionary() {
return this.dictionary;
}
/**
* Gets the xml data of the user configuration.
*
* @return the xml data
* @throws PropertyException the property exception
*/
public byte[] getXmlData() throws PropertyException {
this.validatePropertyAccess(UserConfigurationProperties.XmlData);
return this.xmlData;
}
/**
* Sets the xml data.
*
* @param value the new xml data
*/
public void setXmlData(byte[] value) {
this.xmlData = value;
this.markPropertyForUpdate(UserConfigurationProperties.XmlData);
}
/**
* Gets the binary data of the user configuration.
*
* @return the binary data
* @throws PropertyException the property exception
*/
public byte[] getBinaryData() throws PropertyException {
this.validatePropertyAccess(UserConfigurationProperties.BinaryData);
return this.binaryData;
}
/**
* Sets the binary data.
*
* @param value the new binary data
*/
public void setBinaryData(byte[] value) {
this.binaryData = value;
this.markPropertyForUpdate(UserConfigurationProperties.BinaryData);
}
/**
* Gets a value indicating whether this user configuration has been
* modified.
*
* @return the checks if is dirty
*/
public boolean getIsDirty() {
return (!this.updatedProperties.contains(NoProperties))
|| this.dictionary.getIsDirty();
}
/**
* Binds to an existing user configuration and loads the specified
* property. Calling this method results in a call to EWS.
*
* @param service The service to which the user configuration is bound.
* @param name The name of the user configuration.
* @param parentFolderId The Id of the folder containing the user configuration.
* @param properties The property to load.
* @return A user configuration instance.
* @throws IndexOutOfBoundsException the index out of bounds exception
* @throws Exception the exception
*/
public static UserConfiguration bind(ExchangeService service, String name,
FolderId parentFolderId, UserConfigurationProperties properties)
throws IndexOutOfBoundsException, Exception {
UserConfiguration result = service.getUserConfiguration(name,
parentFolderId, properties);
result.isNew = false;
return result;
}
/**
* Binds to an existing user configuration and loads the specified
* property.
*
* @param service The service to which the user configuration is bound.
* @param name The name of the user configuration.
* @param parentFolderName The name of the folder containing the user configuration.
* @param properties The property to load.
* @return A user configuration instance.
* @throws IndexOutOfBoundsException the index out of bounds exception
* @throws Exception the exception
*/
public static UserConfiguration bind(ExchangeService service, String name,
WellKnownFolderName parentFolderName,
UserConfigurationProperties properties)
throws IndexOutOfBoundsException, Exception {
return UserConfiguration.bind(service, name, new FolderId(
parentFolderName), properties);
}
/**
* Saves the user configuration. Calling this method results in a call to
* EWS.
*
* @param name The name of the user configuration.
* @param parentFolderId The Id of the folder in which to save the user configuration.
* @throws Exception the exception
*/
public void save(String name, FolderId parentFolderId) throws Exception {
EwsUtilities.validateParam(name, "name");
EwsUtilities.validateParam(parentFolderId, "parentFolderId");
parentFolderId.validate(this.service.getRequestedServerVersion());
if (!this.isNew) {
throw new InvalidOperationException(
"Calling Save isn't allowed because this user configuration isn't new. To apply local changes to this user configuration, call Update instead.");
}
this.parentFolderId = parentFolderId;
this.name = name;
this.service.createUserConfiguration(this);
this.isNew = false;
this.resetIsDirty();
}
/**
* Saves the user configuration. Calling this method results in a call to
* EWS.
*
* @param name The name of the user configuration.
* @param parentFolderName The name of the folder in which to save the user
* configuration.
* @throws Exception the exception
*/
public void save(String name, WellKnownFolderName parentFolderName)
throws Exception {
this.save(name, new FolderId(parentFolderName));
}
/**
* Updates the user configuration by applying local changes to the Exchange
* server. Calling this method results in a call to EWS
*
* @throws Exception the exception
*/
public void update() throws Exception {
if (this.isNew) {
throw new InvalidOperationException(
"This user configuration can't be updated because it's never been saved.");
}
if (this.isPropertyUpdated(UserConfigurationProperties.BinaryData)
|| this
.isPropertyUpdated(UserConfigurationProperties.
Dictionary)
|| this.isPropertyUpdated(UserConfigurationProperties.
XmlData)) {
this.service.updateUserConfiguration(this);
}
this.resetIsDirty();
}
/**
* Deletes the user configuration. Calling this method results in a call to
* EWS.
*
* @throws Exception the exception
*/
public void delete() throws Exception {
if (this.isNew) {
throw new InvalidOperationException(
"This user configuration object can't be deleted because it's never been saved.");
} else {
this.service
.deleteUserConfiguration(this.name, this.parentFolderId);
}
}
/**
* Loads the specified property on the user configuration. Calling this
* method results in a call to EWS.
*
* @param properties The property to load.
* @throws Exception the exception
*/
public void load(UserConfigurationProperties properties) throws Exception {
this.initializeProperties(EnumSet.of(properties));
this.service.loadPropertiesForUserConfiguration(this, properties);
}
/**
* Writes to XML.
*
* @param writer The writer.
* @param xmlNamespace The XML namespace.
* @param xmlElementName Name of the XML element.
* @throws Exception the exception
*/
public void writeToXml(EwsServiceXmlWriter writer, XmlNamespace xmlNamespace, String xmlElementName) throws Exception {
EwsUtilities.ewsAssert(writer != null, "UserConfiguration.WriteToXml", "writer is null");
EwsUtilities.ewsAssert(xmlElementName != null, "UserConfiguration.WriteToXml", "xmlElementName is null");
writer.writeStartElement(xmlNamespace, xmlElementName);
// Write the UserConfigurationName element
writeUserConfigurationNameToXml(writer, XmlNamespace.Types, this.name,
this.parentFolderId);
// Write the Dictionary element
if (this.isPropertyUpdated(UserConfigurationProperties.Dictionary)) {
this.dictionary.writeToXml(writer, XmlElementNames.Dictionary);
}
// Write the XmlData element
if (this.isPropertyUpdated(UserConfigurationProperties.XmlData)) {
this.writeXmlDataToXml(writer);
}
// Write the BinaryData element
if (this.isPropertyUpdated(UserConfigurationProperties.BinaryData)) {
this.writeBinaryDataToXml(writer);
}
writer.writeEndElement();
}
/**
* Determines whether the specified property was updated.
*
* @param property property to evaluate.
* @return Boolean indicating whether to send the property Xml.
*/
private boolean isPropertyUpdated(UserConfigurationProperties property) {
boolean isPropertyDirty = false;
boolean isPropertyEmpty = false;
switch (property) {
case Dictionary:
isPropertyDirty = this.getDictionary().getIsDirty();
isPropertyEmpty = this.getDictionary().getCount() == 0;
break;
case XmlData:
isPropertyDirty = this.updatedProperties.contains(property);
isPropertyEmpty = (this.xmlData == null) ||
(this.xmlData.length == 0);
break;
case BinaryData:
isPropertyDirty = this.updatedProperties.contains(property);
isPropertyEmpty = (this.binaryData == null) ||
(this.binaryData.length == 0);
break;
default:
EwsUtilities.ewsAssert(false, "UserConfiguration.IsPropertyUpdated",
"property not supported: " + property.toString());
break;
}
// Consider the property updated, if it's been modified, and either
// . there's a value or
// . there's no value but the operation is update.
return isPropertyDirty && ((!isPropertyEmpty) || (!this.isNew));
}
/**
* Writes the XmlData property to Xml.
*
* @param writer the writer
* @throws XMLStreamException the XML stream exception
* @throws ServiceXmlSerializationException the service xml serialization exception
*/
private void writeXmlDataToXml(EwsServiceXmlWriter writer)
throws XMLStreamException, ServiceXmlSerializationException {
EwsUtilities.ewsAssert(writer != null, "UserConfiguration.WriteXmlDataToXml", "writer is null");
writeByteArrayToXml(writer, this.xmlData, XmlElementNames.XmlData);
}
/**
* Writes the BinaryData property to Xml.
*
* @param writer the writer
* @throws XMLStreamException the XML stream exception
* @throws ServiceXmlSerializationException the service xml serialization exception
*/
private void writeBinaryDataToXml(EwsServiceXmlWriter writer)
throws XMLStreamException, ServiceXmlSerializationException {
EwsUtilities.ewsAssert(writer != null, "UserConfiguration.WriteBinaryDataToXml", "writer is null");
writeByteArrayToXml(writer, this.binaryData,
XmlElementNames.BinaryData);
}
/**
* Loads from XML.
*
* @param reader The reader.
* @throws Exception the exception
*/
public void loadFromXml(EwsServiceXmlReader reader) throws Exception {
EwsUtilities.ewsAssert(reader != null, "UserConfiguration.loadFromXml", "reader is null");
reader.readStartElement(XmlNamespace.Messages,
XmlElementNames.UserConfiguration);
reader.read(); // Position at first property element
do {
if (reader.getNodeType().getNodeType() == XmlNodeType.START_ELEMENT) {
if (reader.getLocalName().equals(
XmlElementNames.UserConfigurationName)) {
String responseName = reader
.readAttributeValue(XmlAttributeNames.Name);
EwsUtilities.ewsAssert(this.name.equals(responseName), "UserConfiguration.loadFromXml",
"UserConfigurationName does not match: Expected: " + this.name
+ " Name in response: " + responseName);
reader.skipCurrentElement();
} else if (reader.getLocalName().equals(XmlElementNames.ItemId)) {
this.itemId = new ItemId();
this.itemId.loadFromXml(reader, XmlElementNames.ItemId);
} else if (reader.getLocalName().equals(
XmlElementNames.Dictionary)) {
this.dictionary.loadFromXml(reader,
XmlElementNames.Dictionary);
} else if (reader.getLocalName()
.equals(XmlElementNames.XmlData)) {
this.xmlData = Base64.decodeBase64(reader.readElementValue());
} else if (reader.getLocalName().equals(
XmlElementNames.BinaryData)) {
this.binaryData = Base64.decodeBase64(reader.readElementValue());
} else {
EwsUtilities.ewsAssert(false, "UserConfiguration.loadFromXml",
"Xml element not supported: " + reader.getLocalName());
}
}
// If XmlData was loaded, read is skipped because GetXmlData
// positions the reader at the next property.
reader.read();
} while (!reader.isEndElement(XmlNamespace.Messages,
XmlElementNames.UserConfiguration));
}
/**
* Initializes property.
*
* @param requestedProperties The property requested for this UserConfiguration.
*/
// / InitializeProperties is called in 3 cases:
// / . Create new object: From the UserConfiguration constructor.
// / . Bind to existing object: Again from the constructor. The constructor
// is called eventually by the GetUserConfiguration request.
// / . Refresh property: From the Load method.
private void initializeProperties(
EnumSet requestedProperties) {
this.itemId = null;
this.dictionary = new UserConfigurationDictionary();
this.xmlData = null;
this.binaryData = null;
this.propertiesAvailableForAccess = requestedProperties;
this.resetIsDirty();
}
/**
* Resets flags to indicate that property haven't been modified.
*/
private void resetIsDirty() {
try {
this.updatedProperties = EnumSet.of(NoProperties);
} catch (Exception e) {
LOG.error(e);
}
this.dictionary.setIsDirty(false);
}
/**
* Determines whether the specified property may be accessed.
*
* @param property Property to access.
* @throws PropertyException the property exception
*/
private void validatePropertyAccess(UserConfigurationProperties property)
throws PropertyException {
if (!this.propertiesAvailableForAccess.contains(property)) {
throw new PropertyException("You must load or assign this property before you can read its value.", property
.toString());
}
}
/**
* Adds the passed property to updatedProperties.
*
* @param property Property to update.
*/
private void markPropertyForUpdate(UserConfigurationProperties property) {
this.updatedProperties.add(property);
this.propertiesAvailableForAccess.add(property);
}
}