/* * Copyright 2015-2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * 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.hawkular.inventory.api; import org.hawkular.inventory.api.model.DataEntity; import org.hawkular.inventory.api.model.StructuredData; import org.hawkular.inventory.api.paging.Page; import org.hawkular.inventory.api.paging.Pager; import org.hawkular.inventory.paths.DataRole; import org.hawkular.inventory.paths.RelativePath; /** * @author Lukas Krejci * @since 0.3.0 */ public final class Data { private Data() { } /** * An interface implemented by Single/Multiple interfaces of entities that can contain data. * @param <Access> the type of access to data */ public interface Container<Access> { Access data(); } public interface Read<Role extends DataRole> extends ReadInterface<Single, Multiple, Role> { } public interface ReadWrite<Role extends DataRole> extends ReadWriteInterface<DataEntity.Update, DataEntity.Blueprint<Role>, Single, Multiple, Role> { @Override Single create(DataEntity.Blueprint<Role> blueprint, boolean cache) throws EntityAlreadyExistsException, ValidationException; @Override default Single create(DataEntity.Blueprint<Role> blueprint) throws EntityAlreadyExistsException { return create(blueprint, true); } @Override void update(Role role, DataEntity.Update update) throws EntityNotFoundException, ValidationException; } public interface Single extends Synced.Single<DataEntity, DataEntity.Blueprint<?>, DataEntity.Update> { /** * Loads the data entity on the current position in the inventory traversal along with its data. * * <p>Note that this might be a potentially expensive operation because of the attached data structure being * loaded. * * @return the fully loaded structured data on the current position in the inventory traversal * @throws EntityNotFoundException if there is no structured data on the current position in the inventory * @see ResolvableToSingle#entity() */ @Override DataEntity entity() throws EntityNotFoundException; /** * Returns the data on the path relative to the entity. * * In another words, you can use this method to obtain only a subset of the data stored on the data entity. * * <p>I.e if you have an data entity which contains a map with a key "foo", which contains a list and you * want to obtain a third element of that list, you'd do: * {@code * ...data(RelativePath.to().structuredData().key("foo").index(2).get()); * } * * <p>If you want to obtain the whole data structure, use an empty path: {@code RelativePath.empty().get()}. * * @param dataPath the path to the subset of the data. * @return the subset of the data stored with the data entity * @see #flatData(RelativePath) */ StructuredData data(RelativePath dataPath); /** * This is very similar to {@link #data(RelativePath)} but this method doesn't load the child data. * * <p>If the data on the path contains a "primitive" value, the value is loaded. If the data contains a list, * the returned instance will contain an empty list and if the data contains a map the returned instance will * contain an empty map. * * @param dataPath the path to the subset of the data to return * @return the subset of the data stored with the data entity */ StructuredData flatData(RelativePath dataPath); @Override default boolean exists() { try { flatData(RelativePath.empty().get()); return true; } catch (EntityNotFoundException | RelationNotFoundException ignored) { return false; } } @Override void update(DataEntity.Update update) throws EntityNotFoundException, RelationNotFoundException, ValidationException; } public interface Multiple extends ResolvableToMany<DataEntity> { /** * Note that this is potentially expensive operation because it loads all the data associated with each of the * returned data entities. * * @param pager the pager object describing the subset of the entities to return * @return the page of the results */ @Override Page<DataEntity> entities(Pager pager); /** * Similar to {@link Single#data(RelativePath)}, only resolved over multiple entities. * * @param dataPath the path to the data entry inside the data entity * @param pager pager to use to page the data * @return the page of the data entries */ Page<StructuredData> data(RelativePath dataPath, Pager pager); /** * Similar to {@link Single#flatData(RelativePath)}, only resolved over multiple entities. * * @param dataPath the path to the data entry inside the data entity * @param pager pager to use to page the data * @return the page of the data entries */ Page<StructuredData> flatData(RelativePath dataPath, Pager pager); @Override default boolean anyExists() { return flatData(RelativePath.empty().get(), Pager.single()).hasNext(); } } }