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())); }
private UserGroupRestRep update() { UserGroupUpdateParam param = new UserGroupUpdateParam(); UserGroupRestRep userGroupRestRep = UserGroupUtils.getUserGroup(this.id); param.setLabel(userGroupRestRep.getName()); param.setDomain(this.domain); Set<UserAttributeParam> oldAttributes = userGroupRestRep.getAttributes(); Set<UserAttributeParam> newAttributes = new HashSet<UserAttributeParam>(); for (AttributeMapping mapping : this.attributes) { if (mapping != null) { newAttributes.add(mapping.createUserAttributeParam()); } } param.getAddAttributes().addAll(newAttributes); param.getAddAttributes().removeAll(oldAttributes); for (UserAttributeParam oldAttribute : oldAttributes) { param.getRemoveAttributes().add(oldAttribute.getKey()); } for (UserAttributeParam newAttribute : newAttributes) { param.getRemoveAttributes().remove(newAttribute.getKey()); } return UserGroupUtils.update(this.id, param); }
// 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())); } } } } } }
private UserGroupRestRep create() { UserGroupCreateParam param = new UserGroupCreateParam(); param.setLabel(this.name); param.setDomain(this.domain); for (AttributeMapping mapping : this.attributes) { if (mapping != null) { param.getAttributes().add(mapping.createUserAttributeParam()); } } return UserGroupUtils.create(param); }
/** * Special handling for polymorphic mapping. Works out the polymorphic type name by evaluating the * function on the feature, then set the relevant sub-type values. * * @param target The target feature to be encoded * @param id The target feature id * @param nestedMapping The mapping that is polymorphic * @param source The source simple feature * @param xpath The xpath of polymorphic type * @param clientPropsMappings Client properties * @throws IOException */ private Attribute setPolymorphicValues( Name mappingName, Attribute target, String id, NestedAttributeMapping nestedMapping, Object source, StepList xpath, Map<Name, Expression> clientPropsMappings) throws IOException { // process sub-type mapping DataAccess<FeatureType, Feature> da = DataAccessRegistry.getDataAccess((Name) mappingName); if (da instanceof AppSchemaDataAccess) { // why wouldn't it be? check just to be safe FeatureTypeMapping fTypeMapping = ((AppSchemaDataAccess) da).getMappingByName((Name) mappingName); List<AttributeMapping> polymorphicMappings = fTypeMapping.getAttributeMappings(); AttributeDescriptor attDescriptor = fTypeMapping.getTargetFeature(); AttributeType type = attDescriptor.getType(); Name polymorphicTypeName = attDescriptor.getName(); StepList prefixedXpath = xpath.clone(); prefixedXpath.add( new Step( new QName( polymorphicTypeName.getNamespaceURI(), polymorphicTypeName.getLocalPart(), this.namespaces.getPrefix(polymorphicTypeName.getNamespaceURI())), 1)); if (!fTypeMapping.getFeatureIdExpression().equals(Expression.NIL)) { id = fTypeMapping.getFeatureIdExpression().evaluate(source, String.class); } Attribute instance = xpathAttributeBuilder.set( target, prefixedXpath, null, id, type, false, attDescriptor, null); setClientProperties(instance, source, clientPropsMappings); for (AttributeMapping mapping : polymorphicMappings) { if (skipTopElement(polymorphicTypeName, mapping, type)) { // if the top level mapping for the Feature itself, the attribute instance // has already been created.. just need to set the client properties setClientProperties(instance, source, mapping.getClientProperties()); continue; } setAttributeValue( instance, null, source, mapping, null, null, selectedProperties.get(mapping)); } return instance; } return null; }
public void readFrom(UserGroupRestRep userGroupRep) { this.id = stringId(userGroupRep); this.name = userGroupRep.getName(); this.domain = userGroupRep.getDomain(); if (!CollectionUtils.isEmpty(userGroupRep.getAttributes())) { for (UserAttributeParam userAttributeMapping : userGroupRep.getAttributes()) { if (userAttributeMapping != null) { AttributeMapping mapping = new AttributeMapping(); mapping.key = userAttributeMapping.getKey(); mapping.values = StringUtils.join(userAttributeMapping.getValues(), "\n"); this.attributes.add(mapping); } } } }
public void skipNestedMapping(AttributeMapping attMapping, List<Feature> sources) throws IOException { if (attMapping instanceof JoiningNestedAttributeMapping) { for (Feature source : sources) { Object value = getValues(attMapping.isMultiValued(), attMapping.getSourceExpression(), source); if (value instanceof Collection) { for (Object val : (Collection) value) { ((JoiningNestedAttributeMapping) attMapping).skip(this, val, getIdValues(source)); } } else { ((JoiningNestedAttributeMapping) attMapping).skip(this, value, getIdValues(source)); } } } }
/** * Create an environment for AppEngine API calls in the context of a request. * * @param envMap a map containing environment variables (from System.getenv()). * @param cache the VM meta-data cache used to retrieve VM attributes. * @param request the HTTP request to get header values from. * @param server the host:port where the VMs API proxy is bound to. * @param wallTimer optional wall clock timer for the current request (required for deadline). * @param millisUntilSoftDeadline optional soft deadline in milliseconds relative to 'wallTimer'. * @return the created Environment object which can be registered with the ApiProxy. */ public static VmApiProxyEnvironment createFromHeaders( Map<String, String> envMap, VmMetadataCache cache, HttpRequest request, String server, Timer wallTimer, Long millisUntilSoftDeadline, VmApiProxyEnvironment defaultEnvironment) { final String longAppId = getEnvOrMetadata(envMap, cache, LONG_APP_ID_KEY, PROJECT_ATTRIBUTE); final String partition = getEnvOrMetadata(envMap, cache, PARTITION_KEY, PARTITION_ATTRIBUTE); final String module = getEnvOrMetadata(envMap, cache, MODULE_NAME_KEY, BACKEND_ATTRIBUTE); final String majorVersion = defaultEnvironment.getMajorVersion(); final String minorVersion = defaultEnvironment.getMinorVersion(); final String appengineHostname = defaultEnvironment.getAppengineHostname(); final boolean useMvmAgent = defaultEnvironment.getUseMvmAgent(); final String instance = getEnvOrMetadata(envMap, cache, INSTANCE_KEY, INSTANCE_ATTRIBUTE); final String affinity = getEnvOrMetadata(envMap, cache, AFFINITY_ENV_KEY, AFFINITY_ATTRIBUTE); final String ticket = request.getHeader(TICKET_HEADER); final String email = request.getHeader(EMAIL_HEADER); boolean admin = false; String value = request.getHeader(IS_ADMIN_HEADER); if (value != null && !value.trim().isEmpty()) { try { admin = Integer.parseInt(value.trim()) != 0; } catch (NumberFormatException e) { throw new IllegalArgumentException(e.getMessage(), e); } } final String authDomain = request.getHeader(AUTH_DOMAIN_HEADER); boolean trustedApp = request.getHeader(IS_TRUSTED_IP_HEADER) != null; Map<String, Object> attributes = new HashMap<>(); // Fill in the attributes from the AttributeMapping. for (AttributeMapping mapping : AttributeMapping.values()) { if (mapping.trustedAppOnly && !trustedApp) { // Do not fill in any trusted app attributes unless the app is trusted. continue; } String headerValue = request.getHeader(mapping.headerKey); if (headerValue != null) { attributes.put(mapping.attributeKey, headerValue); } else if (mapping.defaultValue != null) { attributes.put(mapping.attributeKey, mapping.defaultValue); } // else: The attribute is expected to be missing if the header is not set. } // Fill in the special attributes that do not fit the simple mapping model. boolean federatedId = request.getHeader(AttributeMapping.FEDERATED_IDENTITY.headerKey) != null; attributes.put(IS_FEDERATED_USER_KEY, federatedId); attributes.put(BACKEND_ID_KEY, module); attributes.put(INSTANCE_ID_KEY, instance); attributes.put(AFFINITY_KEY, affinity); if (trustedApp) { // The trusted IP attribute is a boolean. boolean trustedIp = "1".equals(request.getHeader(IS_TRUSTED_IP_HEADER)); attributes.put(IS_TRUSTED_IP_KEY, trustedIp); } VmApiProxyEnvironment requestEnvironment = new VmApiProxyEnvironment( server, ticket, longAppId, partition, module, majorVersion, minorVersion, instance, appengineHostname, email, admin, authDomain, useMvmAgent, wallTimer, millisUntilSoftDeadline, attributes); // Add the thread factories required by the threading API. attributes.put(REQUEST_THREAD_FACTORY_ATTR, new VmRequestThreadFactory(requestEnvironment)); // Since we register VmEnvironmentFactory with ApiProxy in VmRuntimeWebAppContext, // we can use the default thread factory here and don't require any special logic. attributes.put(BACKGROUND_THREAD_FACTORY_ATTR, Executors.defaultThreadFactory()); return requestEnvironment; }
/** * Creates an environment for AppEngine API calls outside the context of a request. * * @param envMap a map containing environment variables (from System.getenv()). * @param cache the VM meta-data cache used to retrieve VM attributes. * @param server the host:port where the VMs API proxy is bound to. * @param wallTimer optional wall clock timer for the current request (required for deadline). * @param millisUntilSoftDeadline optional soft deadline in milliseconds relative to 'wallTimer'. * @param appDir the canonical folder of the application. * @return the created Environment object which can be registered with the ApiProxy. */ public static VmApiProxyEnvironment createDefaultContext( Map<String, String> envMap, VmMetadataCache cache, String server, Timer wallTimer, Long millisUntilSoftDeadline, String appDir) { final String longAppId = getEnvOrMetadata(envMap, cache, LONG_APP_ID_KEY, PROJECT_ATTRIBUTE); final String partition = getEnvOrMetadata(envMap, cache, PARTITION_KEY, PARTITION_ATTRIBUTE); final String module = getEnvOrMetadata(envMap, cache, MODULE_NAME_KEY, BACKEND_ATTRIBUTE); final String majorVersion = getEnvOrMetadata(envMap, cache, VERSION_KEY, VERSION_ATTRIBUTE); String minorVersion = envMap.get(MINOR_VERSION_KEY); if (minorVersion == null) { minorVersion = VmRuntimeUtils.getMinorVersionFromPath(majorVersion, appDir); } final String instance = getEnvOrMetadata(envMap, cache, INSTANCE_KEY, INSTANCE_ATTRIBUTE); final String affinity = getEnvOrMetadata(envMap, cache, AFFINITY_ENV_KEY, AFFINITY_ATTRIBUTE); final String appengineHostname = getEnvOrMetadata(envMap, cache, APPENGINE_HOSTNAME_KEY, APPENGINE_HOSTNAME_ATTRIBUTE); final String ticket = null; final String email = null; final boolean admin = false; final String authDomain = null; final boolean useMvmAgent = Boolean.parseBoolean( getEnvOrMetadata(envMap, cache, USE_MVM_AGENT_KEY, USE_MVM_AGENT_ATTRIBUTE)); Map<String, Object> attributes = new HashMap<>(); // Fill in default attributes values. for (AttributeMapping mapping : AttributeMapping.values()) { if (mapping.trustedAppOnly) { continue; } if (mapping.defaultValue == null) { continue; } attributes.put(mapping.attributeKey, mapping.defaultValue); } attributes.put(IS_FEDERATED_USER_KEY, Boolean.FALSE); attributes.put(BACKEND_ID_KEY, module); attributes.put(INSTANCE_ID_KEY, instance); attributes.put(AFFINITY_KEY, affinity); VmApiProxyEnvironment defaultEnvironment = new VmApiProxyEnvironment( server, ticket, longAppId, partition, module, majorVersion, minorVersion, instance, appengineHostname, email, admin, authDomain, useMvmAgent, wallTimer, millisUntilSoftDeadline, attributes); // Add the thread factories required by the threading API. attributes.put(REQUEST_THREAD_FACTORY_ATTR, new VmRequestThreadFactory(null)); // Since we register VmEnvironmentFactory with ApiProxy in VmRuntimeWebAppContext, // we can use the default thread factory here and don't require any special logic. attributes.put(BACKGROUND_THREAD_FACTORY_ATTR, Executors.defaultThreadFactory()); return defaultEnvironment; }
protected Feature computeNext() throws IOException { String id = getNextFeatureId(); List<Feature> sources = getSources(id); final Name targetNodeName = targetFeature.getName(); AttributeBuilder builder = new AttributeBuilder(attf); builder.setDescriptor(targetFeature); Feature target = (Feature) builder.build(id); for (AttributeMapping attMapping : selectedMapping) { try { if (skipTopElement(targetNodeName, attMapping, targetFeature.getType())) { // ignore the top level mapping for the Feature itself // as it was already set continue; } if (attMapping.isList()) { Attribute instance = setAttributeValue( target, null, sources.get(0), attMapping, null, null, selectedProperties.get(attMapping)); if (sources.size() > 1 && instance != null) { List<Object> values = new ArrayList<Object>(); Expression sourceExpr = attMapping.getSourceExpression(); for (Feature source : sources) { values.add(getValue(sourceExpr, source)); } String valueString = StringUtils.join(values.iterator(), " "); StepList fullPath = attMapping.getTargetXPath(); StepList leafPath = fullPath.subList(fullPath.size() - 1, fullPath.size()); if (instance instanceof ComplexAttributeImpl) { // xpath builder will work out the leaf attribute to set values on xpathAttributeBuilder.set( instance, leafPath, valueString, null, null, false, sourceExpr); } else { // simple attributes instance.setValue(valueString); } } } else if (attMapping.isMultiValued()) { // extract the values from multiple source features of the same id // and set them to one built feature for (Feature source : sources) { setAttributeValue( target, null, source, attMapping, null, null, selectedProperties.get(attMapping)); } } else { String indexString = attMapping.getSourceIndex(); // if not specified, get the first row by default int index = 0; if (indexString != null) { if (ComplexFeatureConstants.LAST_INDEX.equals(indexString)) { index = sources.size() - 1; } else { index = Integer.parseInt(indexString); } } setAttributeValue( target, null, sources.get(index), attMapping, null, null, selectedProperties.get(attMapping)); // When a feature is not multi-valued but still has multiple rows with the same ID in // a denormalised table, by default app-schema only takes the first row and ignores // the rest (see above). The following line is to make sure that the cursors in the // 'joining nested mappings'skip any extra rows that were linked to those rows that are // being ignored. // Otherwise the cursor will stay there in the wrong spot and none of the following // feature chaining // will work. That can really only occur if the foreign key is not unique for the ID of // the parent // feature (otherwise all of those rows would be already passed when creating the feature // based on // the first row). This never really occurs in practice I have noticed, but it is a // theoretic // possibility, as there is no requirement for the foreign key to be unique per id. skipNestedMapping(attMapping, sources.subList(1, sources.size())); } } catch (Exception e) { throw new RuntimeException( "Error applying mapping with targetAttribute " + attMapping.getTargetXPath(), e); } } cleanEmptyElements(target); return target; }
/** * Sets the values of grouping attributes. * * @param target * @param source * @param attMapping * @param values * @return Feature. Target feature sets with simple attributes */ protected Attribute setAttributeValue( Attribute target, String id, final Object source, final AttributeMapping attMapping, Object values, StepList inputXpath, List<PropertyName> selectedProperties) throws IOException { final Expression sourceExpression = attMapping.getSourceExpression(); final AttributeType targetNodeType = attMapping.getTargetNodeInstance(); StepList xpath = inputXpath == null ? attMapping.getTargetXPath().clone() : inputXpath; Map<Name, Expression> clientPropsMappings = attMapping.getClientProperties(); boolean isNestedFeature = attMapping.isNestedAttribute(); if (id == null && Expression.NIL != attMapping.getIdentifierExpression()) { id = extractIdForAttribute(attMapping.getIdentifierExpression(), source); } if (attMapping.isNestedAttribute()) { NestedAttributeMapping nestedMapping = ((NestedAttributeMapping) attMapping); Object mappingName = nestedMapping.getNestedFeatureType(source); if (mappingName != null) { if (nestedMapping.isSameSource() && mappingName instanceof Name) { // data type polymorphism mapping return setPolymorphicValues( (Name) mappingName, target, id, nestedMapping, source, xpath, clientPropsMappings); } else if (mappingName instanceof String) { // referential polymorphism mapping return setPolymorphicReference( (String) mappingName, clientPropsMappings, target, xpath, targetNodeType); } } else { // polymorphism could result in null, to skip the attribute return null; } } if (values == null && source != null) { values = getValues(attMapping.isMultiValued(), sourceExpression, source); } boolean isHRefLink = isByReference(clientPropsMappings, isNestedFeature); if (isNestedFeature) { if (values == null) { // polymorphism use case, if the value doesn't match anything, don't encode return null; } // get built feature based on link value if (values instanceof Collection) { ArrayList<Attribute> nestedFeatures = new ArrayList<Attribute>(((Collection) values).size()); for (Object val : (Collection) values) { if (val instanceof Attribute) { val = ((Attribute) val).getValue(); if (val instanceof Collection) { val = ((Collection) val).iterator().next(); } while (val instanceof Attribute) { val = ((Attribute) val).getValue(); } } if (isHRefLink) { // get the input features to avoid infinite loop in case the nested // feature type also have a reference back to this type // eg. gsml:GeologicUnit/gsml:occurence/gsml:MappedFeature // and gsml:MappedFeature/gsml:specification/gsml:GeologicUnit nestedFeatures.addAll( ((NestedAttributeMapping) attMapping) .getInputFeatures( this, val, getIdValues(source), source, reprojection, selectedProperties, includeMandatory)); } else { nestedFeatures.addAll( ((NestedAttributeMapping) attMapping) .getFeatures( this, val, getIdValues(source), reprojection, source, selectedProperties, includeMandatory)); } } values = nestedFeatures; } else if (isHRefLink) { // get the input features to avoid infinite loop in case the nested // feature type also have a reference back to this type // eg. gsml:GeologicUnit/gsml:occurence/gsml:MappedFeature // and gsml:MappedFeature/gsml:specification/gsml:GeologicUnit values = ((NestedAttributeMapping) attMapping) .getInputFeatures( this, values, getIdValues(source), source, reprojection, selectedProperties, includeMandatory); } else { values = ((NestedAttributeMapping) attMapping) .getFeatures( this, values, getIdValues(source), reprojection, source, selectedProperties, includeMandatory); } if (isHRefLink) { // only need to set the href link value, not the nested feature properties setXlinkReference(target, clientPropsMappings, values, xpath, targetNodeType); return null; } } Attribute instance = null; if (values instanceof Collection) { // nested feature type could have multiple instances as the whole purpose // of feature chaining is to cater for multi-valued properties for (Object singleVal : (Collection) values) { ArrayList valueList = new ArrayList(); // copy client properties from input features if they're complex features // wrapped in app-schema data access if (singleVal instanceof Attribute) { // copy client properties from input features if they're complex features // wrapped in app-schema data access Map<Name, Expression> valueProperties = getClientProperties((Attribute) singleVal); if (!valueProperties.isEmpty()) { clientPropsMappings.putAll(valueProperties); } } if (!isNestedFeature) { if (singleVal instanceof Attribute) { singleVal = ((Attribute) singleVal).getValue(); } if (singleVal instanceof Collection) { valueList.addAll((Collection) singleVal); } else { valueList.add(singleVal); } } else { valueList.add(singleVal); } instance = xpathAttributeBuilder.set( target, xpath, valueList, id, targetNodeType, false, sourceExpression); setClientProperties(instance, source, clientPropsMappings); } } else { if (values instanceof Attribute) { // copy client properties from input features if they're complex features // wrapped in app-schema data access Map<Name, Expression> newClientProps = getClientProperties((Attribute) values); if (!newClientProps.isEmpty()) { newClientProps.putAll(clientPropsMappings); clientPropsMappings = newClientProps; } values = ((Attribute) values).getValue(); } instance = xpathAttributeBuilder.set( target, xpath, values, id, targetNodeType, false, sourceExpression); setClientProperties(instance, source, clientPropsMappings); } if (instance != null && attMapping.encodeIfEmpty()) { instance.getDescriptor().getUserData().put("encodeIfEmpty", attMapping.encodeIfEmpty()); } return instance; }