A WFS DescribeFeatureType request allows you to access to the XML Schema of a feature type, which provides information about the structure of the data and its available properties. By default, TLcdWFSProxyModel automatically requests and processes this information to build up the TLcdDataModel for access to the WFS data. This process is completely transparent to the user. Although TLcdWFSProxyModel is the recommended way to access and use data from a WFS, it is also possible to perform a DescribeFeatureType request manually, process its response, and create the resulting data model:

String featureTypeId = "usrivers";

// Create a client instance. This client automatically performs the version negotiation process,
// retrieves the capabilities and allows users to create and send manual requests.
TLcdWFSClient client = TLcdWFSClient.createWFSClient(new URI("https://sampleservices.luciad.com/wfs?"));

// Create and send a DescribeFeatureTypeRequest.
TLcdWFSDescribeFeatureTypeRequest describeFeatureTypeRequest = client.createDescribeFeatureTypeRequest();
describeFeatureTypeRequest.setTypeName(QName.valueOf(featureTypeId));
TLcdOWSInputStream inputStream = client.describeFeatureType(describeFeatureTypeRequest);

// Store the result in a byte array for easy reuse of the content.
final byte[] bytes = TLcdIOUtil.toByteArray(inputStream);

// Create an XML data model based on the DescribeFeatureType's response.
// We have to supply any dependent data models; in case of WFS 2.0, this is GML 3.2.
TLcdXMLDataModelBuilder builder = new TLcdXMLDataModelBuilder(TLcdGML32DataTypes.getDataModel());
builder.setEntityResolver(createEntityResolver(featureTypeId, bytes));
TLcdDataModel dataModel = builder.createDataModel(null, featureTypeId);

The data model creation relies on an XML entity resolver, which is created as follows:

/**
 * Creates an XML entity resolver that uses the given byte[] content for the specified DescribeFeatureType
 * XML entity, referred to by a system identifier.
 * @param aDescribeFeatureTypeSystemId A system identifier that refers to a DescribeFeatureType XML entity.
 * @param aBytes The byte[] content of the XML entity.
 * @return an XML entity resolver that uses the given byte[] content for the specified DescribeFeatureType XML entity.
 */
private static EntityResolver2 createEntityResolver(String aDescribeFeatureTypeSystemId, byte[] aBytes) {
  // For the system identifier aDescribeFeatureTypeSystemId, we use aBytes
  // For all other system identifiers, we delegate to the default XML entity resolver.
  TLcdXMLEntityResolver defaultResolver = new TLcdXMLEntityResolver();
  return new EntityResolver2() {

    @Override
    public InputSource resolveEntity(String aPublicId, String aSystemId) throws SAXException, IOException {
      if (aDescribeFeatureTypeSystemId.equals(aSystemId)) {
        InputSource inputSource = new InputSource(new ByteArrayInputStream(aBytes));
        inputSource.setSystemId(aSystemId);

        return inputSource;
      }
      return defaultResolver.resolveEntity(aPublicId, aSystemId);
    }

    @Override
    public InputSource resolveEntity(String aName, String aPublicId, String aBaseURI, String aSystemId) throws SAXException, IOException {
      if (aDescribeFeatureTypeSystemId.equals(aSystemId)) {
        InputSource inputSource = new InputSource(new ByteArrayInputStream(aBytes));
        inputSource.setSystemId(aSystemId);
        return inputSource;
      }
      return defaultResolver.resolveEntity(aName, aPublicId, aBaseURI, aSystemId);
    }

    @Override
    public InputSource getExternalSubset(String aName, String aBaseURI) throws SAXException, IOException {
      return defaultResolver.getExternalSubset(aName, aBaseURI);
    }
  };
}