/** * */ package com.thinkbiganalytics.metadata.modeshape.common.mixin; /*- * #%L * kylo-metadata-modeshape * %% * Copyright (C) 2017 ThinkBig Analytics * %% * 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. * #L% */ import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.jcr.Node; import javax.jcr.RepositoryException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.ConstructorUtils; import com.thinkbiganalytics.metadata.modeshape.MetadataRepositoryException; import com.thinkbiganalytics.metadata.modeshape.UnknownPropertyException; import com.thinkbiganalytics.metadata.modeshape.common.JcrObject; import com.thinkbiganalytics.metadata.modeshape.support.JcrPropertyUtil; import com.thinkbiganalytics.metadata.modeshape.support.JcrUtil; /** * * TODO: Refactor hierarchy of JcrObject so that JCR-based entity objects implement * this interface (or one or more mixin subtypes) instead. */ public interface NodeEntityMixin { Node getNode(); default String getTypeName() { try { return getNode().getPrimaryNodeType().getName(); } catch (RepositoryException e) { throw new MetadataRepositoryException("Failed to retrieve the entity type name", e); } } default boolean isNew() { return getNode().isNew(); } default boolean isModified() { return getNode().isModified(); } default void refresh(boolean keepChanges) { try { getNode().refresh(keepChanges); } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to refresh Node. ", e); } } default String getPath() { try { return getNode().getPath(); } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to get the Path", e); } } default String getNodeName() { try { return getNode().getName(); } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to get the Node Name", e); } } default void remove() { try { getNode().remove(); } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to remove the node", e); } } default boolean isLive() { if (getNode() != null) { try { if (getNode().getSession() != null) { return getNode().getSession().isLive(); } } catch (RepositoryException e) { } } return false; } default Map<String, Object> getProperties() { return JcrPropertyUtil.getProperties(getNode()); } default Object getProperty(String name) { return JcrPropertyUtil.getProperty(getNode(), name); } default <T> Set<T> getPropertyAsSet(String name, Class<T> objectType) { Object o = null; try { o = JcrPropertyUtil.getProperty(getNode(), name); } catch (UnknownPropertyException e) { } if (o != null) { if (o instanceof Collection) { //convert the objects to the correct type if needed if (JcrObject.class.isAssignableFrom(objectType)) { Set<T> objects = new HashSet<>(); for (Object collectionObj : (Collection) o) { T obj = null; if (collectionObj instanceof Node) { try { obj = ConstructorUtils.invokeConstructor(objectType, (Node) collectionObj); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { obj = (T) collectionObj; } } else { obj = (T) collectionObj; } objects.add(obj); } return objects; } else { return new HashSet<T>((Collection) o); } } else { Set<T> set = new HashSet<>(); if (JcrObject.class.isAssignableFrom(objectType) && o instanceof Node) { T obj = null; try { obj = ConstructorUtils.invokeConstructor(objectType, (Node) o); set.add((T) obj); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { } set.add(obj); } else { set.add((T) o); } return set; } } return new HashSet<T>(); } default <T> T getProperty(String name, Class<T> type) { return getProperty(name, type, false); } default <T> T getProperty(String name, Class<T> type, boolean allowNotFound) { return getPropertyFromNode(getNode(), name, type, allowNotFound); } default <T> T getPropertyFromNode(Node node, String name, Class<T> type, boolean allowNotFound) { Object o = JcrPropertyUtil.getProperty(node, name, allowNotFound); if (allowNotFound && o == null) { return null; } if (type.isEnum()) { String savedType = o.toString(); if (StringUtils.isNotBlank(savedType)) { Class<? extends Enum> x = (Class<? extends Enum>) type; return (T) Enum.valueOf(x, savedType); } } if (!o.getClass().isAssignableFrom(type)) { //if it cant be matched and it is a Node > JcrObject, do the conversion if (o instanceof Node && JcrObject.class.isAssignableFrom(type)) { return JcrUtil.constructNodeObject((Node) o, type, null); } else { throw new MetadataRepositoryException("Unable to convert Property " + name + " to type " + type); } } else { return (T) o; } } default void setProperty(String name, Object value) { JcrPropertyUtil.setProperty(getNode(), name, value); } }