/**
   * reads a deegree WCS configuration file and performs a DescribeCoverage request Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a DescribeCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testDescribeCoverage() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);

      Map<String, String> map = new HashMap<String, String>();
      map.put("SERVICE", "WCS");
      map.put("REQUEST", "DescribeCoverage");
      map.put("VERSION", "1.0.0");
      map.put("COVERAGE", "europe");

      // StringBuffer sb = new StringBuffer();
      // sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST).append(':').append(
      // Configuration.PORT).append('/').append(Configuration.WCS_WEB_CONTEXT).append(
      // '/').append(Configuration.WCS_SERVLET).append("?service=WCS&").append(
      // "request=DescribeCoverage&version=1.0.0&coverage=europe");

      DescribeCoverage desc = DescribeCoverage.create(map);
      CoverageDescription o = (CoverageDescription) service.doService(desc);
      LOG.logInfo(Arrays.toString(o.getCoverageOfferings()));
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
  /**
   * returns the service section of the configuration/capabilities. vendorspecific capabilities are
   * not supported yet
   *
   * @param namespaceURI
   * @return the service section of the configuration/capabilities. vendorspecific capabilities are
   *     not supported yet
   * @throws InvalidCapabilitiesException
   */
  public Capability getCapabilitySection(URI namespaceURI) throws InvalidCapabilitiesException {
    try {
      Node root = this.getRootElement();

      Element element = XMLTools.getRequiredChildElement("Capability", namespaceURI, root);
      Element elem = XMLTools.getRequiredChildElement("Request", namespaceURI, element);
      OperationsMetadata request = parseOperations(elem, namespaceURI);

      elem = XMLTools.getRequiredChildElement("Exception", namespaceURI, element);
      ExceptionFormat eFormat = getExceptionFormat(elem, namespaceURI);

      // vendorspecific capabilities are not supported yet
      // elem = XMLTools.getRequiredChildByName(
      // "VendorSpecificCapabilities", WCSNS, element);

      String version = element.getAttribute("version");
      if (version == null || version.equals("")) {
        version = this.parseVersion();
      }
      String updateSequence = element.getAttribute("updateSequence");
      if (updateSequence == null || updateSequence.equals("")) {
        updateSequence = this.getRootElement().getAttribute("updateSequence");
      }

      return new Capability(version, updateSequence, request, eFormat, null);

    } catch (XMLParsingException e) {
      String s = e.getMessage();
      throw new InvalidCapabilitiesException(
          "Error while parsing the Capability "
              + "Section of the capabilities\n"
              + s
              + StringTools.stackTraceToString(e));
    }
  }
  /**
   * Creates a <code>DCPType</code> object from the passed <code>DCPType</code> element.
   * <p>
   * NOTE: Currently the <code>OnlineResources</code> included in the <code>DCPType</code> are
   * just stored as simple <code>URLs</code> (not as <code>OnLineResource</code> instances)!
   * <p>
   * NOTE: In an <code>OGCStandardCapabilitiesDocument</code> the <code>XLinks</code> (the
   * <code>URLs</code>) are stored in separate elements (<code>OnlineResource</code>), in
   * an <code>OGCCommonCapabilitiesDocument</code> they are the
   * <code>Get<code>/<code>Post</code> elements themselves.
   *
   * @param element
   * @param namespaceURI
   * @return created <code>DCPType</code>
   * @throws XMLParsingException
   * @see org.deegree.owscommon.OWSCommonCapabilities
   */
  protected DCPType getDCPType(Element element, URI namespaceURI) throws XMLParsingException {
    try {
      Element elem = XMLTools.getRequiredChildElement("HTTP", namespaceURI, element);
      ElementList el = XMLTools.getChildElements("Get", namespaceURI, elem);

      URL[] get = new URL[el.getLength()];
      for (int i = 0; i < get.length; i++) {
        Element ell = XMLTools.getRequiredChildElement("OnlineResource", namespaceURI, el.item(i));
        String s = XMLTools.getRequiredAttrValue("href", XLNNS, ell);
        get[i] = new URL(s);
      }
      el = XMLTools.getChildElements("Post", namespaceURI, elem);

      URL[] post = new URL[el.getLength()];
      for (int i = 0; i < post.length; i++) {
        Element ell = XMLTools.getRequiredChildElement("OnlineResource", namespaceURI, el.item(i));
        String s = XMLTools.getRequiredAttrValue("href", XLNNS, ell);
        post[i] = new URL(s);
      }
      Protocol protocol = new HTTP(get, post);
      return new DCPType(protocol);
    } catch (MalformedURLException e) {
      throw new XMLParsingException(
          "Couldn't parse DCPType onlineresoure URL about\n" + StringTools.stackTraceToString(e));
    }
  }
  /**
   * creates a <tt>MetadataLink</tt> object from the passed element.
   *
   * @param element
   * @return created <tt>MetadataLink</tt>
   * @throws XMLParsingException
   */
  @Override
  protected MetadataLink parseMetadataLink(Element element) throws XMLParsingException {
    if (element == null) return null;

    try {
      URL reference = new URL(XMLTools.getAttrValue(element, "xlink:href"));
      String title = XMLTools.getAttrValue(element, "xlink:title");
      URI about = new URI(XMLTools.getAttrValue(element, null, "about", null));
      String tmp = XMLTools.getAttrValue(element, null, "metadataType", null);
      MetadataType metadataType = new MetadataType(tmp);
      return new MetadataLink(reference, title, about, metadataType);
    } catch (MalformedURLException e) {
      throw new XMLParsingException(
          "Couldn't parse metadataLink reference\n" + StringTools.stackTraceToString(e));
    } catch (URISyntaxException e) {
      throw new XMLParsingException(
          "Couldn't parse metadataLink about\n" + StringTools.stackTraceToString(e));
    }
  }
  /**
   * performs the creation of a <tt>ImageGridCoverage</tt> from the source assigned to this reader.
   *
   * @param parameters
   * @throws IOException
   */
  private GridCoverage performECW(GeneralParameterValueIm[] parameters) throws IOException {

    BufferedImage bi = null;
    CoverageOffering co = null;
    Object[] o = null;

    ECWReader ecwFile = null;
    try {
      String s = ((File) source).getName();
      ecwFile = new ECWReader(s);

      // get the requested dimension in pixels
      int reqWidth = 0;
      int reqHeight = 0;
      for (int i = 0; i < parameters.length; i++) {
        OperationParameterIm op = (OperationParameterIm) parameters[i].getDescriptor();
        String name = op.getName();
        if (name.equalsIgnoreCase("WIDTH")) {
          Object vo = op.getDefaultValue();
          reqWidth = ((Integer) vo).intValue();
        } else if (name.equalsIgnoreCase("HEIGHT")) {
          Object vo = op.getDefaultValue();
          reqHeight = ((Integer) vo).intValue();
        }
      }

      // calculate image region of interest
      o = getECWImageRegion(reqWidth, reqHeight);
      Envelope envl = (Envelope) o[1];

      Rectangle rect = (Rectangle) o[0];
      bi = ecwFile.getBufferedImage(envl, rect.width, rect.height);

      // create a coverage description that matches the sub image (coverage)
      // for this a new LonLatEnvelope must be set
      co = (CoverageOffering) description.clone();
      co.setLonLatEnvelope((LonLatEnvelope) o[2]);

    } catch (Exception e) {
      e.printStackTrace();
      throw new IOException(StringTools.stackTraceToString(e));
    } finally {
      // free the ECW cache memory
      if (ecwFile != null) {
        ecwFile.close();
      }
    }

    return new ImageGridCoverage(co, (Envelope) o[1], bi);
  }
  /** return the LonLatEnvelope of the entire image in "EPSG:4326" */
  private Envelope getLLEAsEnvelope() {
    String code = getNativeSRSCode();
    LonLatEnvelope lle = description.getLonLatEnvelope();
    Envelope tmp =
        GeometryFactory.createEnvelope(
            lle.getMin().getX(),
            lle.getMin().getY(),
            lle.getMax().getX(),
            lle.getMax().getY(),
            null);
    try {
      if (!code.equals("EPSG:4326")) {
        GeoTransformer trans = new GeoTransformer(code);
        tmp = trans.transform(tmp, "EPSG:4326");
      }
    } catch (Exception e) {
      LOGGER.logError(StringTools.stackTraceToString(e));
    }

    return tmp;
  }
  /**
   * reads a deegree WCS configuration file and performs a GetCoverage request Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a GetCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testGetCoverage1() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);
      StringBuffer sb = new StringBuffer();
      sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST)
          .append(':')
          .append(Configuration.PORT)
          .append(Configuration.WCS_WEB_CONTEXT)
          .append('/')
          .append(Configuration.WCS_SERVLET);

      String req =
          "<?xml version='1.0' encoding='UTF-8'?><GetCoverage "
              + "xmlns='http://www.opengis.net/wcs' xmlns:gml='http://www.opengis.net/gml' "
              + "service='WCS' version='1.0.0'><sourceCoverage>Mapneatline</sourceCoverage>"
              + "<domainSubset><spatialSubset><gml:Envelope srsName='EPSG:4326'>"
              + "<gml:pos dimension='2'>-1,-1</gml:pos><gml:pos dimension='2'>1,1"
              + "</gml:pos></gml:Envelope><gml:Grid dimension='2'><gml:limits>"
              + "<gml:GridEnvelope><gml:low>0 0</gml:low><gml:high>300 300</gml:high>"
              + "</gml:GridEnvelope></gml:limits><gml:axisName>x</gml:axisName>"
              + "<gml:axisName>y</gml:axisName></gml:Grid></spatialSubset></domainSubset>"
              + "<output><crs>EPSG:4326</crs><format>jpeg</format></output></GetCoverage>";
      StringReader reader = new StringReader(req);
      Document doc = XMLTools.parse(reader);

      GetCoverage desc = (GetCoverage) OGCRequestFactory.createFromXML(doc);
      ResultCoverage o = (ResultCoverage) service.doService(desc);
      BufferedImage bi = ((AbstractGridCoverage) o.getCoverage()).getAsImage(500, 500);

      FileOutputStream fos =
          new FileOutputStream(Configuration.getWCSBaseDir().getPath() + "/kannweg1.tif");
      ImageUtils.saveImage(bi, fos, "tif", 1);
      fos.close();
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
 /**
  * reads a deegree WCS configuration file and performs a GetCapbilities request Steps:
  *
  * <ul>
  *   <li>read configuration file
  *   <li>read a GetCapabilites request object
  *   <li>perform the request
  * </ul>
  */
 public void testGetCapabilities() {
   try {
     WCSConfiguration configuration =
         WCSConfiguration.create(Configuration.getWCSConfigurationURL());
     WCService service = new WCService(configuration);
     // StringBuffer sb = new StringBuffer();
     // sb.append( "http://127.0.0.1/deegreewcs/wcs?service=WCS&" );
     // sb.append( "request=GetCapabilities&version=1.0.0" );
     Map<String, String> map = new HashMap<String, String>();
     map.put("REQUEST", "GetCapabilities");
     map.put("VERSION", "1.0.0");
     map.put("SERVICE", "WCS");
     WCSGetCapabilities getCapa = (WCSGetCapabilities) WCSGetCapabilities.create(map);
     // (WCSGetCapabilities) OGCRequestFactory.createFromKVP(sb.toString());
     Object o = service.doService(getCapa);
     XMLFragment xml = XMLFactory.export((WCSConfiguration) o);
     // xml.write( System.out );
     LOG.logInfo(xml.getAsPrettyString());
   } catch (Exception e) {
     fail(StringTools.stackTraceToString(e));
   }
 }
  /**
   * Creates a <code>DCPType</code> object from the passed <code>DCP</code> element.
   * <p>
   * NOTE: Currently the <code>OnlineResources</code> included in the <code>DCPType</code> are
   * just stored as simple <code>URLs</code> (not as <code>OnLineResource</code> instances)!
   * <p>
   * NOTE: In an <code>OGCStandardCapabilitiesDocument</code> the <code>XLinks</code> (the
   * <code>URLs</code>) are stored in separate elements (<code>OnlineResource</code>), in
   * an <code>OGCCommonCapabilitiesDocument</code> they are the
   * <code>Get<code>/<code>Post</code> elements themselves.
   *
   * @param element
   *
   * @return created <code>DCPType</code>
   * @throws XMLParsingException
   *
   * @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities
   */
  @Override
  protected DCPType getDCP(Element element) throws XMLParsingException {
    LOG.entering();
    DCPType dcpType = null;
    try {
      Element elem = (Element) XMLTools.getRequiredNode(element, "HTTP", nsContext);
      List nl = XMLTools.getNodes(elem, "Get", nsContext);

      URL[] get = new URL[nl.size()];
      for (int i = 0; i < get.length; i++) {
        String s = XMLTools.getNodeAsString((Node) nl.get(i), "./@xlink:href", nsContext, null);
        if (s == null) {
          s =
              XMLTools.getRequiredNodeAsString(
                  (Node) nl.get(i), "./OnlineResource/@xlink:href", nsContext);
        }
        get[i] = new URL(s);
      }
      nl = XMLTools.getNodes(elem, "Post", nsContext);

      URL[] post = new URL[nl.size()];
      for (int i = 0; i < post.length; i++) {
        String s = XMLTools.getNodeAsString((Node) nl.get(i), "./@xlink:href", nsContext, null);
        if (s == null) {
          s =
              XMLTools.getRequiredNodeAsString(
                  (Node) nl.get(i), "./OnlineResource/@xlink:href", nsContext);
        }
        post[i] = new URL(s);
      }
      Protocol protocol = new HTTP(get, post);
      dcpType = new DCPType(protocol);
    } catch (MalformedURLException e) {
      throw new XMLParsingException(
          "Couldn't parse DCPType onlineresource URL about: " + StringTools.stackTraceToString(e));
    }
    LOG.exiting();
    return dcpType;
  }
  /**
   * reads a deegree WCS configuration file and performs a GetCoverage request Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a GetCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testGetCoverage3() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);

      Map<String, String> map = new HashMap<String, String>();
      map.put("SERVICE", "WCS");
      map.put("REQUEST", "GetCoverage");
      map.put("VERSION", "1.0.0");
      map.put("COVERAGE", "europe");
      map.put("CRS", "EPSG:4326");
      map.put("BBOX", "-5,40,20,60");
      map.put("WIDTH", "800");
      map.put("HEIGHT", "800");
      map.put("FORMAT", "jpeg");

      // StringBuffer sb = new StringBuffer();
      // sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST)
      // .append(':').append(Configuration.PORT).append('/')
      // .append(Configuration.WCS_WEB_CONTEXT).append('/')
      // .append(Configuration.WCS_SERVLET).append("?service=WCS&")
      // .append("request=GetCoverage&version=1.0.0&coverage=europe&")
      // .append( "crs=EPSG:4326&BBOX=-5,40,20,60&Width=800&height=800&")
      // .append("format=jpeg");
      GetCoverage desc = GetCoverage.create(map);
      ResultCoverage o = (ResultCoverage) service.doService(desc);
      BufferedImage bi = ((AbstractGridCoverage) o.getCoverage()).getAsImage(800, 800);

      FileOutputStream fos =
          new FileOutputStream(Configuration.getWCSBaseDir().getPath() + "/kannweg3.tif");
      ImageUtils.saveImage(bi, fos, "tif", 1);
      fos.close();
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
  /**
   * reads a deegree WCS configuration file and performs a GetCoverage request. same as
   * testGetCoverage1() but uses nameIndexed data source Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a GetCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testGetCoverage2() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);

      Map<String, String> map = new HashMap<String, String>();
      map.put("SERVICE", "WCS");
      map.put("REQUEST", "GetCoverage");
      map.put("VERSION", "1.0.0");
      map.put("COVERAGE", "dem");
      map.put("CRS", "EPSG:4326");
      map.put("BBOX", "-122.6261,37.4531,-122.0777,38.0");
      map.put("WIDTH", "828");
      map.put("HEIGHT", "823");
      map.put("FORMAT", "GeoTiff");

      // StringBuffer sb = new StringBuffer();
      // sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST).append(':').append(
      // Configuration.PORT).append('/').append(Configuration.WCS_WEB_CONTEXT).append(
      // '/').append(Configuration.WCS_SERVLET).append("?service=WCS&").append(
      // "request=GetCoverage&version=1.0.0&coverage=dem&").append(
      // "crs=EPSG:4326&BBOX=-122.6261,37.4531,-122.0777,38.0&Width=828&height=823&")
      // .append("format=GeoTiff");
      GetCoverage desc = GetCoverage.create(map);
      ResultCoverage o = (ResultCoverage) service.doService(desc);
      BufferedImage bi = ((AbstractGridCoverage) o.getCoverage()).getAsImage(828, 823);
      LOG.logInfo(o.toString());
      FileOutputStream fos =
          new FileOutputStream(new URL(Configuration.getWCSBaseDir(), "/kannweg2.tif").getFile());
      ImageUtils.saveImage(bi, fos, "tif", 1);
      fos.close();
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
 /** @param arg0 */
 public UnauthorizedException(Throwable arg0) {
   super(StringTools.stackTraceToString(arg0));
 }
 /**
  * @param message
  * @param arg1
  */
 public UnauthorizedException(String message, Throwable arg1) {
   super(message, arg1);
   this.message = message + StringTools.stackTraceToString(arg1);
 }
  /**
   * Creates a class representation of the <code>deegreeParams</code>- section.
   *
   * @return
   * @throws InvalidConfigurationException
   */
  public CatalogueDeegreeParams getDeegreeParams() throws InvalidConfigurationException {

    CatalogueDeegreeParams deegreeParams = null;

    try {
      Node root = this.getRootElement();
      Element element = XMLTools.getRequiredChildElement("deegreeParams", DEEGREECSW, root);

      // 'deegreecsw:DefaultOnlineResource'-element (mandatory)
      OnlineResource defaultOnlineResource =
          parseOnLineResource(
              XMLTools.getRequiredChildElement("DefaultOnlineResource", DEEGREECSW, element));

      // 'deegreecsw:CacheSize'-element (optional, default: 100)
      int cacheSize = XMLTools.getNodeAsInt(element, "./deegreecsw:CacheSize", nsContext, 100);

      // 'deegreecsw:RequestTimeLimit'-element (optional, default: 2)
      int requestTimeLimit =
          XMLTools.getNodeAsInt(element, "./deegreecsw:RequestTimeLimit", nsContext, 2);

      // 'deegreecsw:Encoding'-element (optional, default: UTF-8)
      String characterSet = XMLTools.getStringValue("Encoding", DEEGREECSW, element, "UTF-8");

      // default output schema used by a catalogue
      String defaultOutputSchema =
          XMLTools.getStringValue("DefaultOutputSchema", DEEGREECSW, element, "OGCCORE");

      // 'deegreecsw:WFSResource'-element (mandatory)
      SimpleLink wfsResource =
          parseSimpleLink(XMLTools.getRequiredChildElement("WFSResource", DEEGREECSW, element));

      // 'deegreecsw:CatalogAddresses'-element (optional)
      Element catalogAddressesElement =
          XMLTools.getChildElement("CatalogAddresses", DEEGREECSW, element);
      OnlineResource[] catalogAddresses = new OnlineResource[0];
      if (catalogAddressesElement != null) {
        // 'deegreecsw:CatalogAddresses'-element (optional)
        ElementList el =
            XMLTools.getChildElements("CatalogAddress", DEEGREECSW, catalogAddressesElement);
        catalogAddresses = new OnlineResource[el.getLength()];
        for (int i = 0; i < catalogAddresses.length; i++) {
          catalogAddresses[i] = parseOnLineResource(el.item(i));
        }
      }

      OnlineResource transInXslt = null;
      Element elem = (Element) XMLTools.getNode(element, "deegreecsw:TransactionInputXSLT", nsc);
      if (elem != null) {
        transInXslt = parseOnLineResource(elem);
      }
      OnlineResource transOutXslt = null;
      elem = (Element) XMLTools.getNode(element, "deegreecsw:TransactionOutputXSLT", nsc);
      if (elem != null) {
        transOutXslt = parseOnLineResource(elem);
      }
      if ((transInXslt != null && transOutXslt == null)
          || (transInXslt == null && transOutXslt != null)) {
        throw new InvalidConfigurationException(
            "if CSW-deegreeParam "
                + "'TransactionInputXSLT' is defined 'TransactionOutputXSLT' must "
                + "be defined too and vice versa!");
      }

      // 'deegreecsw:HarvestRepository'-element (optional)
      Element harvestRepositoryElement =
          XMLTools.getChildElement("HarvestRepository", DEEGREECSW, element);
      JDBCConnection harvestRepository = null;
      if (harvestRepositoryElement != null) {
        // 'deegreecsw:Connection'-element (optional)
        Element connectionElement =
            XMLTools.getChildElement("Connection", DEEGREECSW, harvestRepositoryElement);
        if (connectionElement != null) {
          harvestRepository =
              new JDBCConnection(
                  XMLTools.getRequiredStringValue("Driver", DEEGREECSW, connectionElement),
                  XMLTools.getRequiredStringValue("Logon", DEEGREECSW, connectionElement),
                  XMLTools.getRequiredStringValue("User", DEEGREECSW, connectionElement),
                  XMLTools.getRequiredStringValue("Password", DEEGREECSW, connectionElement),
                  null,
                  null,
                  null);
        }
      }
      deegreeParams =
          new CatalogueDeegreeParams(
              defaultOnlineResource,
              cacheSize,
              requestTimeLimit,
              characterSet,
              wfsResource,
              catalogAddresses,
              harvestRepository,
              defaultOutputSchema,
              transInXslt,
              transOutXslt);
    } catch (XMLParsingException e) {
      throw new InvalidConfigurationException(
          "Error parsing the deegreeParams "
              + "section of the CSW configuration: \n"
              + e.getMessage()
              + StringTools.stackTraceToString(e));
    }
    return deegreeParams;
  }