// properties can only be set by constructor, before initialising source features
  // (for joining nested mappings)
  private void setPropertyNames(Collection<PropertyName> propertyNames) {
    selectedProperties = new HashMap<AttributeMapping, List<PropertyName>>();

    if (propertyNames == null) {
      selectedMapping = mapping.getAttributeMappings();
    } else {
      final AttributeDescriptor targetDescriptor = mapping.getTargetFeature();
      selectedMapping = new ArrayList<AttributeMapping>();

      for (AttributeMapping attMapping : mapping.getAttributeMappings()) {
        final StepList targetSteps = attMapping.getTargetXPath();
        boolean alreadyAdded = false;

        if (includeMandatory) {
          PropertyName targetProp = namespaceAwareFilterFactory.property(targetSteps.toString());
          Object descr = targetProp.evaluate(targetDescriptor.getType());
          if (descr instanceof PropertyDescriptor) {
            if (((PropertyDescriptor) descr).getMinOccurs() >= 1) {
              selectedMapping.add(attMapping);
              selectedProperties.put(attMapping, new ArrayList<PropertyName>());
              alreadyAdded = true;
            }
          }
        }

        for (PropertyName requestedProperty : propertyNames) {
          StepList requestedPropertySteps;
          if (requestedProperty.getNamespaceContext() == null) {
            requestedPropertySteps =
                XPath.steps(targetDescriptor, requestedProperty.getPropertyName(), namespaces);
          } else {
            requestedPropertySteps =
                XPath.steps(
                    targetDescriptor,
                    requestedProperty.getPropertyName(),
                    requestedProperty.getNamespaceContext());
          }
          if (requestedPropertySteps == null
              ? AppSchemaDataAccess.matchProperty(requestedProperty.getPropertyName(), targetSteps)
              : AppSchemaDataAccess.matchProperty(requestedPropertySteps, targetSteps)) {
            if (!alreadyAdded) {
              selectedMapping.add(attMapping);
              selectedProperties.put(attMapping, new ArrayList<PropertyName>());
              alreadyAdded = true;
            }
            if (requestedPropertySteps != null
                && requestedPropertySteps.size() > targetSteps.size()) {
              List<PropertyName> pnList = selectedProperties.get(attMapping);
              StepList subProperty =
                  requestedPropertySteps.subList(targetSteps.size(), requestedPropertySteps.size());
              pnList.add(
                  filterFac.property(
                      subProperty.toString(), requestedProperty.getNamespaceContext()));
            }
          }
        }
      }
    }
  }
 protected Object getValues(
     boolean isMultiValued, Expression expression, Object sourceFeatureInput) {
   if (isMultiValued
       && sourceFeatureInput instanceof FeatureImpl
       && expression instanceof AttributeExpressionImpl) {
     // RA: Feature Chaining
     // complex features can have multiple nodes of the same attribute.. and if they are used
     // as input to an app-schema data access to be nested inside another feature type of a
     // different XML type, it has to be mapped like this:
     // <AttributeMapping>
     // <targetAttribute>
     // gsml:composition
     // </targetAttribute>
     // <sourceExpression>
     // <inputAttribute>mo:composition</inputAttribute>
     // <linkElement>gsml:CompositionPart</linkElement>
     // <linkField>gml:name</linkField>
     // </sourceExpression>
     // <isMultiple>true</isMultiple>
     // </AttributeMapping>
     // As there can be multiple nodes of mo:composition in this case, we need to retrieve
     // all of them
     AttributeExpressionImpl attribExpression = ((AttributeExpressionImpl) expression);
     String xpath = attribExpression.getPropertyName();
     ComplexAttribute sourceFeature = (ComplexAttribute) sourceFeatureInput;
     StepList xpathSteps = XPath.steps(sourceFeature.getDescriptor(), xpath, namespaces);
     return getProperties(sourceFeature, xpathSteps);
   }
   return expression.evaluate(sourceFeatureInput);
 }
 protected boolean skipTopElement(
     Name topElement, AttributeMapping attMapping, AttributeType type) {
   // don't skip if there's OCQL
   return XPath.equals(topElement, attMapping.getTargetXPath())
       && (attMapping.getSourceExpression() == null
           || Expression.NIL.equals(attMapping.getSourceExpression()));
 }
Example #4
0
  /**
   *
   *
   * <pre>
   * </pre>
   *
   * @param targetFeature
   * @return
   * @throws Exception
   */
  public static List /* <AttributeMapping> */ createMappingsColumnsAndValues(
      AttributeDescriptor targetFeature) throws Exception {

    List mappings = new LinkedList();
    AttributeMapping attMapping;
    Expression source;
    String target;

    FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);

    source = ff.literal("ph");
    target = "sample/measurement[1]/parameter";
    // empty nssupport as the test properties have no namespace
    NamespaceSupport namespaces = new NamespaceSupport();
    attMapping = new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces));
    mappings.add(attMapping);

    source = ff.property("ph");
    target = "sample/measurement[1]/value";
    attMapping = new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces));
    mappings.add(attMapping);

    source = ff.literal("temp");
    target = "sample/measurement[2]/parameter";
    attMapping = new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces));
    mappings.add(attMapping);

    source = ff.property("temp");
    target = "sample/measurement[2]/value";
    attMapping = new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces));
    mappings.add(attMapping);

    source = ff.literal("turbidity");
    target = "sample/measurement[3]/parameter";
    attMapping = new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces));
    mappings.add(attMapping);

    source = ff.property("turbidity");
    target = "sample/measurement[3]/value";
    attMapping = new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces));
    mappings.add(attMapping);

    return mappings;
  }
  protected Attribute setAttributeContent(
      Attribute target,
      StepList xpath,
      Object value,
      String id,
      AttributeType targetNodeType,
      boolean isXlinkRef,
      Expression sourceExpression,
      Object source,
      final Map<Name, Expression> clientProperties,
      boolean ignoreXlinkHref) {
    Attribute instance = null;

    Map<Name, Expression> properties = new HashMap<Name, Expression>(clientProperties);

    if (ignoreXlinkHref) {
      properties.remove(XLINK_HREF_NAME);
    }

    if (properties.containsKey(XLINK_HREF_NAME) && resolveDepth > 0) {
      // local resolve

      String refid =
          referenceToIdentifier(getValue(properties.get(XLINK_HREF_NAME), source).toString());

      if (refid != null) {

        final Hints hints = new Hints();
        if (resolveDepth > 1) {
          hints.put(Hints.RESOLVE, ResolveValueType.ALL);
          // only the top-level resolve thread should monitor timeout
          hints.put(Hints.RESOLVE_TIMEOUT, Integer.MAX_VALUE);
          hints.put(Hints.ASSOCIATION_TRAVERSAL_DEPTH, resolveDepth - 1);
        } else {
          hints.put(Hints.RESOLVE, ResolveValueType.NONE);
        }

        // let's try finding it
        FeatureFinder finder = new FeatureFinder(refid, hints);
        // this will be null if joining or sleeping is interrupted
        Feature foundFeature = null;
        if (resolveTimeOut == Integer.MAX_VALUE) {
          // not the top-level resolve thread so do not monitor timeout
          finder.run();
          foundFeature = finder.getFeature();
        } else {
          Thread thread = new Thread(finder);
          long startTime = System.currentTimeMillis();
          thread.start();
          try {
            while (thread.isAlive()
                && (System.currentTimeMillis() - startTime) / 1000 < resolveTimeOut) {
              Thread.sleep(RESOLVE_TIMEOUT_POLL_INTERVAL);
            }
            thread.interrupt();
            // joining ensures synchronisation
            thread.join();
            foundFeature = finder.getFeature();
          } catch (InterruptedException e) {
            // clean up as best we can
            thread.interrupt();
            throw new RuntimeException("Interrupted while resolving resource " + refid);
          }
        }

        if (foundFeature != null) {
          // found it
          instance =
              xpathAttributeBuilder.set(
                  target,
                  xpath,
                  Collections.singletonList(foundFeature),
                  id,
                  targetNodeType,
                  false,
                  sourceExpression);
          properties.remove(XLINK_HREF_NAME);
        }
      }
    }

    if (instance == null) {
      instance =
          xpathAttributeBuilder.set(
              target, xpath, value, id, targetNodeType, false, sourceExpression);
    }

    setClientProperties(instance, source, properties);

    return instance;
  }
  public AbstractMappingFeatureIterator(
      AppSchemaDataAccess store,
      FeatureTypeMapping mapping,
      Query query,
      Query unrolledQuery,
      boolean removeQueryLimitIfDenormalised,
      boolean hasPostFilter)
      throws IOException {
    this.store = store;
    this.attf = new AppSchemaFeatureFactoryImpl();

    this.mapping = mapping;

    // validate and initialise resolve options
    Hints hints = query.getHints();
    ResolveValueType resolveVal = (ResolveValueType) hints.get(Hints.RESOLVE);
    boolean resolve =
        ResolveValueType.ALL.equals(resolveVal) || ResolveValueType.LOCAL.equals(resolveVal);
    if (!resolve && resolveVal != null && !ResolveValueType.NONE.equals(resolveVal)) {
      throw new IllegalArgumentException(
          "Resolve:" + resolveVal.getName() + " is not supported in app-schema!");
    }
    Integer atd = (Integer) hints.get(Hints.ASSOCIATION_TRAVERSAL_DEPTH);
    resolveDepth = resolve ? atd == null ? 0 : atd : 0;
    resolveTimeOut = (Integer) hints.get(Hints.RESOLVE_TIMEOUT);

    namespaces = mapping.getNamespaces();
    namespaceAwareFilterFactory = new FilterFactoryImplNamespaceAware(namespaces);

    Object includeProps = query.getHints().get(Query.INCLUDE_MANDATORY_PROPS);
    includeMandatory = includeProps instanceof Boolean && ((Boolean) includeProps).booleanValue();

    if (mapping.isDenormalised()) {
      // we need to disable the max number of features retrieved so we can
      // sort them manually just in case the data is denormalised.  Do this
      // by overriding the max features for this query just before executing
      // it.  Note that the original maxFeatures value was copied to
      // this.requestMaxFeatures in the constructor and will be re-applied after
      // the rows have been returned
      if (removeQueryLimitIfDenormalised) {
        this.dataMaxFeatures = 1000000;
        if (hasPostFilter) {
          // true max features will be handled in PostFilteringMappingFeatureIterator
          this.requestMaxFeatures = 1000000;
        } else {
          this.requestMaxFeatures = query.getMaxFeatures();
        }
      } else {
        this.dataMaxFeatures = query.getMaxFeatures();
        this.requestMaxFeatures = query.getMaxFeatures();
      }
    } else {
      this.requestMaxFeatures = query.getMaxFeatures();
      this.dataMaxFeatures = query.getMaxFeatures();
    }

    if (unrolledQuery == null) {
      unrolledQuery = getUnrolledQuery(query);
      if (query instanceof JoiningQuery && unrolledQuery instanceof JoiningQuery) {
        ((JoiningQuery) unrolledQuery).setRootMapping(((JoiningQuery) query).getRootMapping());
      }
    }

    // NC - property names
    if (query != null && query.getProperties() != null) {
      setPropertyNames(query.getProperties());
    } else {
      setPropertyNames(null); // we need the actual property names (not surrogates) to do
      // this...
    }
    xpathAttributeBuilder = new XPath();
    xpathAttributeBuilder.setFeatureFactory(attf);
    initialiseSourceFeatures(mapping, unrolledQuery, query.getCoordinateSystemReproject());
    xpathAttributeBuilder.setFilterFactory(namespaceAwareFilterFactory);
  }
Example #7
0
  /**
   * Flat FeatureType:
   *
   * <ul>
   *   wq_ir_results
   *   <li>station_no
   *   <li>sitename
   *   <li>anzlic_no
   *   <li>project_no
   *   <li>id
   *   <li>sample_collection_date
   *   <li>determinand_description
   *   <li>results_value
   *   <li>location
   * </ul>
   *
   * <p>Complex type:
   *
   * <ul>
   *   wq_plus
   *   <li>sitename
   *   <li>anzlic_no
   *   <li>project_no
   *   <li>location
   *   <li>measurement (0..*)
   *       <ul>
   *         <li>determinand_description
   *         <li>result
   *       </ul>
   * </ul>
   *
   * <p>Mappings definition:
   *
   * <pre>
   *       &lt;strong&gt;wq_ir_results&lt;/strong&gt;			&lt;strong&gt;wq_plus&lt;/strong&gt;
   *        station_no		--&gt;	wq_plus@id
   *        sitename		--&gt;	sitename
   *        anzlic_no		--&gt;	anzlic_no
   *        project_no		--&gt;	project_no
   *        id		--&gt;	measurement/@id
   *        sample_collection_date--&gt; [not used]
   *        determinand_description--&gt;measurement/determinand_description
   *        results_value		--&gt;measurement/result
   *        location		--&gt;location
   * </pre>
   *
   * @param simpleStore
   * @return
   * @throws Exception
   */
  public static FeatureTypeMapping createMappingsGroupByStation(MemoryDataStore simpleStore)
      throws Exception {
    Name sourceTypeName = WATERSAMPLE_TYPENAME;
    final SimpleFeatureSource wsSource = simpleStore.getFeatureSource(sourceTypeName);

    FeatureType targetType = createComplexWaterQualityType();
    FeatureTypeFactory tf = new UniqueNameFeatureTypeFactoryImpl();
    AttributeDescriptor targetFeature =
        tf.createAttributeDescriptor(
            targetType, targetType.getName(), 0, Integer.MAX_VALUE, true, null);

    List mappings = new LinkedList();
    Expression id;
    Expression source;
    String target;

    FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);

    id = ff.property("station_no");
    source = Expression.NIL;
    target = "wq_plus";
    NamespaceSupport namespaces = new NamespaceSupport();
    mappings.add(new AttributeMapping(id, source, XPath.steps(targetFeature, target, namespaces)));

    source = ff.property("sitename");
    target = "wq_plus/sitename";
    mappings.add(
        new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces)));

    source = ff.property("anzlic_no");
    target = "wq_plus/anzlic_no";
    mappings.add(
        new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces)));

    source = ff.property("project_no");
    target = "wq_plus/project_no";
    mappings.add(
        new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces)));

    id = ff.property("id[1]");
    source = null;
    target = "wq_plus/measurement";
    mappings.add(
        new AttributeMapping(
            id, source, XPath.steps(targetFeature, target, namespaces), null, true, null));

    source = ff.property("determinand_description");
    target = "wq_plus/measurement/determinand_description";
    mappings.add(
        new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces)));

    source = ff.property("results_value");
    target = "wq_plus/measurement/result";
    mappings.add(
        new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces)));

    source = ff.property("location");
    target = "wq_plus/location";
    mappings.add(
        new AttributeMapping(null, source, XPath.steps(targetFeature, target, namespaces)));

    return new FeatureTypeMapping(wsSource, targetFeature, mappings, namespaces);
  }
 public NestedAttributeExpression(Expression expression, FeatureTypeMapping mappings) {
   super(expression.toString());
   this.mappings = mappings;
   fullSteps =
       XPath.steps(mappings.getTargetFeature(), this.attPath.toString(), mappings.getNamespaces());
 }