blob: 311a9036cd410b8d79beed4de1808950ed8a2bf0 [file] [log] [blame]
/*
* Copyright (c) OSGi Alliance (2016). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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.apache.felix.schematizer.impl;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import org.apache.felix.schematizer.Node;
import org.osgi.util.converter.TypeReference;
public class NodeImpl implements Node {
private final String name;
private final Object type;
private final boolean isCollection;
private final String absolutePath;
private NodeImpl parent;
private HashMap<String, NodeImpl> children = new HashMap<>();
private Field field;
public NodeImpl(
String aName,
Object aType,
boolean isACollection,
String anAbsolutePath ) {
name = aName;
type = aType;
isCollection = isACollection;
absolutePath = anAbsolutePath;
}
@SuppressWarnings( { "unchecked", "rawtypes" } )
public NodeImpl(Node.DTO dto, String contextPath, Function<String, Type> f, Map<String, NodeImpl> nodes) {
name = dto.name;
type = f.apply(dto.type);
isCollection = dto.isCollection;
absolutePath = contextPath + dto.path;
for (Node.DTO child : dto.children.values()) {
NodeImpl node;
if (child.isCollection)
try {
node = new CollectionNode(child, contextPath, f, nodes, (Class)getClass().getClassLoader().loadClass(child.collectionType));
} catch ( ClassNotFoundException e ) {
node = new CollectionNode(child, contextPath, f, nodes, (Class)Collection.class);
}
else
node = new NodeImpl(child, contextPath, f, nodes);
children.put("/" + child.name, node);
nodes.put(child.path, node);
}
}
@Override
public String name() {
return name;
}
@Override
public Type type() {
if (type instanceof TypeReference)
return ((TypeReference<?>)type).getType();
return (Type)type;
}
@Override
public Optional<TypeReference<?>> typeReference() {
if (type instanceof TypeReference)
return Optional.of((TypeReference<?>)type);
return Optional.empty();
}
@Override
public boolean isCollection() {
return isCollection;
}
@Override
public String absolutePath() {
return absolutePath;
}
@Override
public Field field() {
return field;
}
public void field(Field aField) {
field = aField;
}
@SuppressWarnings( { "unchecked", "rawtypes" } )
@Override
public Map<String, Node> children() {
return (Map)childrenInternal();
}
@Override
public Class<? extends Collection<?>> collectionType() {
return null;
}
@SuppressWarnings( { "unchecked", "rawtypes" } )
Map<String, NodeImpl> childrenInternal() {
return (Map)children.clone();
}
NodeImpl parent() {
return parent;
}
void parent(NodeImpl aParent) {
parent = aParent;
}
void add(NodeImpl child) {
children.put(child.absolutePath, child);
}
void add(Map<String, NodeImpl> moreChildren) {
children.putAll(moreChildren);
}
public Node.DTO toDTO() {
Node.DTO dto = new Node.DTO();
dto.name = name();
dto.path = absolutePath();
dto.type = type().getTypeName();
dto.isCollection = isCollection();
childrenInternal().values().stream().forEach(v -> dto.children.put(v.name, v.toDTO()));
return dto;
}
@Override
public String toString() {
return absolutePath;
}
}