org.camunda.bpm.engine.rest.hal.HalLinker Maven / Gradle / Ivy
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.camunda.bpm.engine.rest.hal;
import org.camunda.bpm.engine.ProcessEngine;
import java.util.*;
import java.util.Map.Entry;
/**
* A stateful linker which collects information about the links it creates.
*
* @author Daniel Meyer
*
*/
public class HalLinker {
/**
* linked resource ids by {@link HalRelation}
*/
Map> linkedResources = new HashMap>();
protected final Hal hal;
/**
* The HalResource on which the links are constructed
*/
protected final HalResource resource;
public HalLinker(Hal hal, HalResource resource) {
this.hal = hal;
this.resource = resource;
}
/**
* Creates a link in a given relation.
*
* @param rel the {@link HalRelation} for which a link should be constructed
* @param pathParams the path params to populate the url template with.
* */
public void createLink(HalRelation rel, String... pathParams) {
if(pathParams != null && pathParams.length > 0 && pathParams[0] != null) {
Set linkedResourceIds = linkedResources.get(rel);
if(linkedResourceIds == null) {
linkedResourceIds = new HashSet();
linkedResources.put(rel, linkedResourceIds);
}
// Hmm... use the last id in the pathParams as linked resource id
linkedResourceIds.add(pathParams[pathParams.length - 1]);
resource.addLink(rel.relName, rel.uriTemplate.build((Object[])pathParams));
}
}
public Set getLinkedRelations() {
return linkedResources.keySet();
}
public Set getLinkedResourceIdsByRelation(HalRelation relation) {
Set result = linkedResources.get(relation);
if(result != null) {
return result;
} else {
return Collections.emptySet();
}
}
/**
* Resolves a relation. Locates a HalLinkResolver for resolving the set of all linked resources in the relation.
*
* @param relation the relation to resolve
* @param processEngine the process engine to use
* @return the list of resolved resources
* @throws RuntimeException if no HalLinkResolver can be found for the linked resource type.
*/
public List> resolve(HalRelation relation, ProcessEngine processEngine) {
HalLinkResolver linkResolver = hal.getLinkResolver(relation.resourceType);
if(linkResolver != null) {
Set linkedIds = getLinkedResourceIdsByRelation(relation);
if(!linkedIds.isEmpty()) {
return linkResolver.resolveLinks(linkedIds.toArray(new String[linkedIds.size()]), processEngine);
} else {
return Collections.emptyList();
}
} else {
throw new RuntimeException("Cannot find HAL link resolver for resource type '"+relation.resourceType+"'.");
}
}
/**
* merge the links of an embedded resource into this linker.
* This is useful when building resources which are actually resource collections.
* You can then merge the relations of all resources in the collection and the unique the set of linked resources to embed.
*
* @param embedded the embedded resource for which the links should be merged into this linker.
*/
public void mergeLinks(HalResource embedded) {
for (Entry> linkentry : embedded.linker.linkedResources.entrySet()) {
Set linkedIdSet = linkedResources.get(linkentry.getKey());
if(linkedIdSet != null) {
linkedIdSet.addAll(linkentry.getValue());
}else {
linkedResources.put(linkentry.getKey(), linkentry.getValue());
}
}
}
}