/**
  * Validate request.
  *
  * @throws Exception the exception
  */
 @Override
 protected void validate() throws Exception {
   super.validate();
   EwsUtilities.validateParamCollection(this.getAttachments().iterator(), "Attachments");
   for (int i = 0; i < this.getAdditionalProperties().size(); i++) {
     EwsUtilities.validateParam(
         this.getAdditionalProperties().get(i), String.format("AdditionalProperties[%d]", i));
   }
 }
  /**
   * Initializes a new instance of the StreamingSubscriptionConnection class.
   *
   * @param service The ExchangeService instance this connection uses to connect to the server.
   * @param lifetime The maximum time, in minutes, the connection will remain open. Lifetime must be
   *     between 1 and 30.
   * @throws Exception
   */
  public StreamingSubscriptionConnection(ExchangeService service, int lifetime) throws Exception {
    EwsUtilities.validateParam(service, "service");

    EwsUtilities.validateClassVersion(
        service, ExchangeVersion.Exchange2010_SP1, this.getClass().getName());

    if (lifetime < 1 || lifetime > 30) {
      throw new ArgumentOutOfRangeException("lifetime");
    }

    this.session = service;
    this.subscriptions = new HashMap<String, StreamingSubscription>();
    this.connectionTimeout = lifetime;
  }
  /**
   * Creates the WS-Security header necessary to send with an outgoing request.
   *
   * @param xmlWriter The XML writer to serialize the headers to.
   * @throws javax.xml.stream.XMLStreamException the xML stream exception
   */
  @Override
  public void serializeWSSecurityHeaders(XMLStreamWriter xmlWriter) throws XMLStreamException {
    EwsUtilities.EwsAssert(
        this.securityToken != null,
        "WSSecurityBasedCredentials.SerializeWSSecurityHeaders",
        "Security token cannot be null!");

    // <wsu:Timestamp wsu:Id="_timestamp">
    //   <wsu:Created>2007-09-20T01:13:10.468Z</wsu:Created>
    //   <wsu:Expires>2007-09-20T01:18:10.468Z</wsu:Expires>
    // </wsu:Timestamp>
    //
    String timestamp = null;
    if (this.addTimestamp) {
      Calendar utcNow = Calendar.getInstance();
      utcNow.add(Calendar.MINUTE, 5);
      timestamp = String.format(WSSecurityBasedCredentials.wsuTimeStampFormat, utcNow, utcNow);
    }

    // Format the WS-Security header based on all the information we have.
    String wsSecurityHeader =
        String.format(
            WSSecurityBasedCredentials.wsSecurityHeaderFormat, timestamp + this.securityToken);

    // And write the header out...
    xmlWriter.writeCharacters(wsSecurityHeader);
  }
 /**
  * Reads the attribute from XML.
  *
  * @param reader the reader
  * @throws Exception the exception
  */
 @Override
 public void readAttributesFromXml(EwsServiceXmlReader reader) throws Exception {
   this.id = reader.readAttributeValue(XmlAttributeNames.Id);
   this.name = reader.readAttributeValue(XmlAttributeNames.Name);
   this.bias =
       EwsUtilities.getXSDurationToTimeSpan(reader.readAttributeValue(XmlAttributeNames.Bias));
 }
 /**
  * Writes the attribute to XML.
  *
  * @param writer the writer
  * @throws ServiceXmlSerializationException the service xml serialization exception
  */
 @Override
 public void writeAttributesToXml(EwsServiceXmlWriter writer)
     throws ServiceXmlSerializationException {
   writer.writeAttributeValue(
       XmlAttributeNames.Bias, EwsUtilities.getTimeSpanToXSDuration(this.bias));
   writer.writeAttributeValue(XmlAttributeNames.Name, this.name);
   writer.writeAttributeValue(XmlAttributeNames.Id, this.id);
 }
 /**
  * Validate request..
  *
  * @throws Exception the exception
  */
 @Override
 protected void validate() throws Exception {
   super.validate();
   EwsUtilities.validateParamCollection(this.getDelegateUsers().iterator(), "DelegateUsers");
   for (DelegateUser delegateUser : this.getDelegateUsers()) {
     delegateUser.validateUpdateDelegate();
   }
 }
 /**
  * Initializes a new instance of the StreamingSubscriptionConnection class.
  *
  * @param service The ExchangeService instance this connection uses to connect to the server.
  * @param subscriptions Iterable subcriptions
  * @param lifetime The maximum time, in minutes, the connection will remain open. Lifetime must be
  *     between 1 and 30.
  * @throws Exception
  */
 public StreamingSubscriptionConnection(
     ExchangeService service, Iterable<StreamingSubscription> subscriptions, int lifetime)
     throws Exception {
   this(service, lifetime);
   EwsUtilities.validateParamCollection(subscriptions.iterator(), "subscriptions");
   for (StreamingSubscription subscription : subscriptions) {
     this.subscriptions.put(subscription.getId(), subscription);
   }
 }
  /**
   * The owner of this attachment collection.
   *
   * @param value accepts ServiceObject
   */
  public void setOwner(ServiceObject value) {
    Item item = (Item) value;
    EwsUtilities.ewsAssert(
        item != null,
        "AttachmentCollection.IOwnedProperty.set_Owner",
        "value is not a descendant of ItemBase");

    this.owner = item;
  }
  /**
   * Reads the SOAP fault.
   *
   * @param reader The reader.
   * @return SOAP fault details.
   */
  private SoapFaultDetails readSoapFault(EwsXmlReader reader) {
    SoapFaultDetails soapFaultDetails = null;

    try {

      reader.read();
      if (reader.getNodeType().getNodeType() == XmlNodeType.START_DOCUMENT) {
        reader.read();
      }
      if (!reader.isStartElement()
          || (!reader.getLocalName().equals(XmlElementNames.SOAPEnvelopeElementName))) {
        return null;
      }

      // Get the namespace URI from the envelope element and use it for
      // the rest of the parsing.
      // If it's not 1.1 or 1.2, we can't continue.
      XmlNamespace soapNamespace = EwsUtilities.getNamespaceFromUri(reader.getNamespaceUri());
      if (soapNamespace == XmlNamespace.NotSpecified) {
        return null;
      }

      reader.read();

      // Skip SOAP header.
      if (reader.isStartElement(soapNamespace, XmlElementNames.SOAPHeaderElementName)) {
        do {
          reader.read();
        } while (!reader.isEndElement(soapNamespace, XmlElementNames.SOAPHeaderElementName));

        // Queue up the next read
        reader.read();
      }

      // Parse the fault element contained within the SOAP body.
      if (reader.isStartElement(soapNamespace, XmlElementNames.SOAPBodyElementName)) {
        do {
          reader.read();

          // Parse Fault element
          if (reader.isStartElement(soapNamespace, XmlElementNames.SOAPFaultElementName)) {
            soapFaultDetails = SoapFaultDetails.parse(reader, soapNamespace);
          }
        } while (!reader.isEndElement(soapNamespace, XmlElementNames.SOAPBodyElementName));
      }

      reader.readEndElement(soapNamespace, XmlElementNames.SOAPEnvelopeElementName);
    } catch (Exception e) {
      // If response doesn't contain a valid SOAP fault, just ignore
      // exception and
      // return null for SOAP fault details.
      e.printStackTrace();
    }

    return soapFaultDetails;
  }
  /**
   * Creates the WS-Addressing headers necessary to send with an outgoing request.
   *
   * @param xmlWriter The XML writer to serialize the headers to.
   * @param webMethodName The Web method being called.
   * @throws javax.xml.stream.XMLStreamException the xML stream exception
   */
  private void serializeWSAddressingHeaders(XMLStreamWriter xmlWriter, String webMethodName)
      throws XMLStreamException {
    EwsUtilities.EwsAssert(
        webMethodName != null,
        "WSSecurityBasedCredentials.SerializeWSAddressingHeaders",
        "Web method name cannot be null!");

    EwsUtilities.EwsAssert(
        this.ewsUrl != null,
        "WSSecurityBasedCredentials.SerializeWSAddressingHeaders",
        "EWS Url cannot be null!");

    // Format the WS-Addressing headers.
    String wsAddressingHeaders =
        String.format(
            WSSecurityBasedCredentials.wsAddressingHeadersFormat, webMethodName, this.ewsUrl);

    // And write them out...
    xmlWriter.writeCharacters(wsAddressingHeaders);
  }
  /**
   * Removes the specified streaming subscription from the connection.
   *
   * @param subscription The subscription to remove.
   * @throws Exception Thrown when RemoveSubscription is called while connected.
   */
  public void removeSubscription(StreamingSubscription subscription) throws Exception {
    this.throwIfDisposed();

    EwsUtilities.validateParam(subscription, "subscription");

    this.validateConnectionState(false, "Subscriptions can't be removed from an open connection.");

    synchronized (this) {
      this.subscriptions.remove(subscription.getId());
    }
  }
  /**
   * Adds a subscription to this connection.
   *
   * @param subscription The subscription to add.
   * @throws Exception Thrown when AddSubscription is called while connected.
   */
  public void addSubscription(StreamingSubscription subscription) throws Exception {
    this.throwIfDisposed();
    EwsUtilities.validateParam(subscription, "subscription");
    this.validateConnectionState(false, "Subscriptions can't be added to an open connection.");

    synchronized (this) {
      if (this.subscriptions.containsKey(subscription.getId())) {
        return;
      }
      this.subscriptions.put(subscription.getId(), subscription);
    }
  }
  /**
   * Adds an item attachment to the collection.
   *
   * @param <TItem> the generic type
   * @param cls the cls
   * @return An ItemAttachment instance.
   * @throws Exception the exception
   */
  public <TItem extends Item> GenericItemAttachment<TItem> addItemAttachment(Class<TItem> cls)
      throws Exception {
    if (cls.getDeclaredFields().length == 0) {
      throw new InvalidOperationException(
          String.format("Items of type %s are not supported as attachments.", cls.getName()));
    }

    GenericItemAttachment<TItem> itemAttachment = new GenericItemAttachment<TItem>(this.owner);
    itemAttachment.setTItem(
        (TItem) EwsUtilities.createItemFromItemClass(itemAttachment, cls, true));

    this.internalAdd(itemAttachment);

    return itemAttachment;
  }
  /**
   * Writes elements to XML.
   *
   * @param writer accepts EwsServiceXmlWriter
   * @throws Exception throws Exception
   */
  @Override
  public void writeElementsToXml(EwsServiceXmlWriter writer) throws Exception {
    if (this.offset != null) {
      writer.writeElementValue(
          XmlNamespace.Types,
          XmlElementNames.Offset,
          EwsUtilities.getTimeSpanToXSDuration(this.getOffset()));
    }

    if (this.recurrence != null) {
      this.recurrence.writeToXml(writer, XmlElementNames.RelativeYearlyRecurrence);
    }

    if (this.absoluteDate != null) {
      writer.writeElementValue(
          XmlNamespace.Types,
          XmlElementNames.AbsoluteDate,
          EwsUtilities.dateTimeToXSDate(this.getAbsoluteDate()));
    }

    if (this.time != null) {
      writer.writeElementValue(XmlNamespace.Types, XmlElementNames.Time, this.getTime().toXSTime());
    }
  }
  /**
   * Tries to read element from XML.
   *
   * @param reader accepts EwsServiceXmlReader
   * @return True if element was read
   * @throws Exception throws Exception
   */
  @Override
  public boolean tryReadElementFromXml(EwsServiceXmlReader reader) throws Exception {

    if (reader.getLocalName().equalsIgnoreCase(XmlElementNames.Offset)) {
      this.offset = EwsUtilities.getXSDurationToTimeSpan(reader.readElementValue());
      return true;
    } else if (reader.getLocalName().equalsIgnoreCase(XmlElementNames.RelativeYearlyRecurrence)) {
      this.recurrence = new TimeChangeRecurrence();
      this.recurrence.loadFromXml(reader, reader.getLocalName());
      return true;
    } else if (reader.getLocalName().equalsIgnoreCase(XmlElementNames.AbsoluteDate)) {
      SimpleDateFormat sdfin = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
      Date tempDate = sdfin.parse(reader.readElementValue());
      this.absoluteDate = tempDate;
      return true;
    } else if (reader.getLocalName().equalsIgnoreCase(XmlElementNames.Time)) {
      SimpleDateFormat sdfin = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
      Date tempDate = sdfin.parse(reader.readElementValue());
      this.time = new Time(tempDate);
      return true;
    } else {
      return false;
    }
  }
  /**
   * Parses the message xml.
   *
   * @param reader the reader
   * @throws Exception the exception
   * @throws ServiceXmlDeserializationException the service xml deserialization exception
   */
  private void parseMessageXml(EwsXmlReader reader)
      throws Exception, ServiceXmlDeserializationException, Exception {
    // E14:172881: E12 and E14 return the MessageXml element in different
    // namespaces (types namespace for E12, errors namespace in E14). To
    // avoid this problem, the parser will match the namespace from the
    // start and end elements.
    XmlNamespace elementNS = EwsUtilities.getNamespaceFromUri(reader.getNamespaceUri());

    if (!reader.isEmptyElement()) {
      do {
        reader.read();

        if (reader.isStartElement() && !reader.isEmptyElement()) {
          String localName = reader.getLocalName();
          if (localName.equals(XmlElementNames.Value)) {
            this.errorDetails.put(
                reader.readAttributeValue(XmlAttributeNames.Name), reader.readElementValue());
          }
        }
      } while (!reader.isEndElement(elementNS, XmlElementNames.MessageXml));
    } else {
      reader.read();
    }
  }
  /**
   * Writes the autodiscover SOAP request.
   *
   * @param requestUrl Request URL.
   * @throws javax.xml.stream.XMLStreamException the xML stream exception
   * @throws microsoft.exchange.webservices.data.exception.ServiceXmlSerializationException the
   *     service xml serialization exception
   */
  protected void writeSoapRequest(URI requestUrl, EwsServiceXmlWriter writer)
      throws XMLStreamException, ServiceXmlSerializationException {

    if (writer.isRequireWSSecurityUtilityNamespace()) {
      writer.writeAttributeValue(
          "xmlns",
          EwsUtilities.WSSecurityUtilityNamespacePrefix,
          EwsUtilities.WSSecurityUtilityNamespace);
    }
    writer.writeStartDocument();
    writer.writeStartElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
    writer.writeAttributeValue(
        "xmlns",
        EwsUtilities.getNamespacePrefix(XmlNamespace.Soap),
        EwsUtilities.getNamespaceUri(XmlNamespace.Soap));
    writer.writeAttributeValue(
        "xmlns",
        EwsUtilities.AutodiscoverSoapNamespacePrefix,
        EwsUtilities.AutodiscoverSoapNamespace);
    writer.writeAttributeValue(
        "xmlns", EwsUtilities.WSAddressingNamespacePrefix, EwsUtilities.WSAddressingNamespace);
    writer.writeAttributeValue(
        "xmlns",
        EwsUtilities.EwsXmlSchemaInstanceNamespacePrefix,
        EwsUtilities.EwsXmlSchemaInstanceNamespace);

    writer.writeStartElement(XmlNamespace.Soap, XmlElementNames.SOAPHeaderElementName);

    if (this.service.getCredentials() != null) {
      this.service.getCredentials().emitExtraSoapHeaderNamespaceAliases(writer.getInternalWriter());
    }

    writer.writeElementValue(
        XmlNamespace.Autodiscover,
        XmlElementNames.RequestedServerVersion,
        this.service.getRequestedServerVersion().toString());

    writer.writeElementValue(
        XmlNamespace.WSAddressing, XmlElementNames.Action, this.getWsAddressingActionName());

    writer.writeElementValue(XmlNamespace.WSAddressing, XmlElementNames.To, requestUrl.toString());

    this.writeExtraCustomSoapHeadersToXml(writer);

    if (this.service.getCredentials() != null) {
      this.service.getCredentials().serializeWSSecurityHeaders(writer.getInternalWriter());
    }

    this.service.doOnSerializeCustomSoapHeaders(writer.getInternalWriter());

    writer.writeEndElement(); // soap:Header

    writer.writeStartElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);

    this.writeBodyToXml(writer);

    writer.writeEndElement(); // soap:Body
    writer.writeEndElement(); // soap:Envelope
    writer.flush();
    writer.dispose();
  }
  /**
   * Removes the specified attachment.
   *
   * @param attachment The attachment to remove.
   * @return True if the attachment was successfully removed from the collection, false otherwise.
   * @throws Exception the exception
   */
  public boolean remove(Attachment attachment) throws Exception {
    EwsUtilities.validateParam(attachment, "attachment");

    return this.internalRemove(attachment);
  }
  /**
   * Initializes a new instance of the UpdateFolderResponse class.
   *
   * @param folder The folder
   */
  public UpdateFolderResponse(Folder folder) {
    super();
    EwsUtilities.ewsAssert(folder != null, "UpdateFolderResponse.ctor", "folder is null");

    this.folder = folder;
  }
 /**
  * Validate request.
  *
  * @throws microsoft.exchange.webservices.data.exception.ServiceLocalException the service local
  *     exception
  * @throws Exception the exception
  */
 protected void validate() throws ServiceLocalException, Exception {
   super.validate();
   EwsUtilities.validateParamCollection(this.getItemIds().iterator(), "ItemIds");
 }
  /**
   * Executes this instance.
   *
   * @return the autodiscover response
   * @throws ServiceLocalException the service local exception
   * @throws Exception the exception
   */
  protected AutodiscoverResponse internalExecute() throws ServiceLocalException, Exception {
    this.validate();
    HttpWebRequest request = null;
    try {
      request = this.service.prepareHttpWebRequestForUrl(this.url);
      this.service.traceHttpRequestHeaders(TraceFlags.AutodiscoverRequestHttpHeaders, request);

      boolean needSignature =
          this.getService().getCredentials() != null
              && this.getService().getCredentials().isNeedSignature();
      boolean needTrace = this.getService().isTraceEnabledFor(TraceFlags.AutodiscoverRequest);

      OutputStream urlOutStream = request.getOutputStream();
      // OutputStreamWriter out = new OutputStreamWriter(request
      // .getOutputStream());

      ByteArrayOutputStream memoryStream = new ByteArrayOutputStream();
      EwsServiceXmlWriter writer = new EwsServiceXmlWriter(this.getService(), memoryStream);
      writer.setRequireWSSecurityUtilityNamespace(needSignature);
      this.writeSoapRequest(this.url, writer);

      if (needSignature) {
        this.service.getCredentials().sign(memoryStream);
      }

      if (needTrace) {
        memoryStream.flush();
        this.service.traceXml(TraceFlags.AutodiscoverRequest, memoryStream);
      }
      memoryStream.writeTo(urlOutStream);
      urlOutStream.flush();
      urlOutStream.close();
      memoryStream.close();
      // out.write(memoryStream.toString());
      // out.close();
      request.executeRequest();
      request.getResponseCode();
      if (AutodiscoverRequest.isRedirectionResponse(request)) {
        AutodiscoverResponse response = this.createRedirectionResponse(request);
        if (response != null) {
          return response;
        } else {
          throw new ServiceRemoteException("The service returned an invalid redirection response.");
        }
      }

      /*
       * BufferedReader in = new BufferedReader(new
       * InputStreamReader(request.getInputStream()));
       *
       * String decodedString;
       *
       * while ((decodedString = in.readLine()) != null) {
       * System.out.println(decodedString); } in.close();
       */

      memoryStream = new ByteArrayOutputStream();
      InputStream serviceResponseStream = request.getInputStream();

      while (true) {
        int data = serviceResponseStream.read();
        if (-1 == data) {
          break;
        } else {
          memoryStream.write(data);
        }
      }
      memoryStream.flush();
      serviceResponseStream.close();

      if (this.service.isTraceEnabled()) {
        this.service.traceResponse(request, memoryStream);
      }
      ByteArrayInputStream memoryStreamIn = new ByteArrayInputStream(memoryStream.toByteArray());
      EwsXmlReader ewsXmlReader = new EwsXmlReader(memoryStreamIn);

      // WCF may not generate an XML declaration.
      ewsXmlReader.read();
      if (ewsXmlReader.getNodeType().getNodeType() == XmlNodeType.START_DOCUMENT) {
        ewsXmlReader.readStartElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
      } else if ((ewsXmlReader.getNodeType().getNodeType() != XmlNodeType.START_ELEMENT)
          || (!ewsXmlReader.getLocalName().equals(XmlElementNames.SOAPEnvelopeElementName))
          || (!ewsXmlReader
              .getNamespaceUri()
              .equals(EwsUtilities.getNamespaceUri(XmlNamespace.Soap)))) {
        throw new ServiceXmlDeserializationException(
            "The Autodiscover service response was invalid.");
      }

      this.readSoapHeaders(ewsXmlReader);

      AutodiscoverResponse response = this.readSoapBody(ewsXmlReader);

      ewsXmlReader.readEndElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);

      if (response.getErrorCode() == AutodiscoverErrorCode.NoError) {
        return response;
      } else {
        throw new AutodiscoverResponseException(
            response.getErrorCode(), response.getErrorMessage());
      }

    } catch (XMLStreamException ex) {
      this.service.traceMessage(
          TraceFlags.AutodiscoverConfiguration,
          String.format("XML parsing error: %s", ex.getMessage()));

      // Wrap exception
      throw new ServiceRequestException(
          String.format("The request failed. %s", ex.getMessage()), ex);
    } catch (IOException ex) {
      this.service.traceMessage(
          TraceFlags.AutodiscoverConfiguration, String.format("I/O error: %s", ex.getMessage()));

      // Wrap exception
      throw new ServiceRequestException(
          String.format("The request failed. %s", ex.getMessage()), ex);
    } catch (Exception ex) {
      // HttpWebRequest httpWebResponse = (HttpWebRequest)ex;

      if (null != request && request.getResponseCode() == 7) {
        if (AutodiscoverRequest.isRedirectionResponse(request)) {
          this.service.processHttpResponseHeaders(
              TraceFlags.AutodiscoverResponseHttpHeaders, request);

          AutodiscoverResponse response = this.createRedirectionResponse(request);
          if (response != null) {
            return response;
          }
        } else {
          this.processWebException(ex, request);
        }
      }

      // Wrap exception if the above code block didn't throw
      throw new ServiceRequestException(
          String.format("The request failed. %s", ex.getMessage()), ex);
    } finally {
      try {
        if (request != null) {
          request.close();
        }
      } catch (Exception e) {
        // do nothing
      }
    }
  }