/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.isis.applib.services.repository; import java.util.List; import com.google.common.base.Predicate; import org.apache.isis.applib.annotation.Programmatic; import org.apache.isis.applib.query.Query; public interface RepositoryService { /** * Normally any queries are automatically preceded by flushing pending executions. * * <p> * This key allows this behaviour to be disabled. * * <p> * Originally introduced as part of ISIS-1134 (fixing memory leaks in the objectstore) * where it was found that the autoflush behaviour was causing a (now unrepeatable) * data integrity error (see <a href="https://issues.apache.org/jira/browse/ISIS-1134?focusedCommentId=14500638&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14500638">ISIS-1134 comment</a>, in the isis-module-security. * However, that this could be circumvented by removing the call to flush(). * We don't want to break existing apps that might rely on this behaviour, on the * other hand we want to fix the memory leak. Adding this configuration property * seems the most prudent way forward. * </p> */ String KEY_DISABLE_AUTOFLUSH = "isis.services.container.disableAutoFlush"; /** * Same as {@link org.apache.isis.applib.services.factory.FactoryService#instantiate(Class)}; provided as a * convenience because instantiating and {@link #persist(Object) persisting} are often done together. */ @Programmatic <T> T instantiate(final Class<T> ofType); /** * Determines if the specified object is persistent (that it is stored permanently outside of the virtual machine * in the object store). */ @Programmatic boolean isPersistent(Object domainObject); /** * Persist the specified object (or do nothing if already persistent). * * <p> * It is recommended that the object be initially instantiated using * {@link org.apache.isis.applib.DomainObjectContainer#newTransientInstance(Class)}. However, the framework will also * handle the case when the object is simply <i>new()</i>ed up. * * @see org.apache.isis.applib.DomainObjectContainer#newTransientInstance(Class) * @see #isPersistent(Object) */ @Programmatic void persist(Object domainObject); /** * Persist the specified object (or do nothing if already persistent) and flushes changes to the database. * * @see #persist(Object) */ @Programmatic void persistAndFlush(Object domainObject); /** * Deletes the domain object but only if is persistent. * * @param domainObject */ @Programmatic void remove(Object domainObject); /** * Deletes the domain object but only if is persistent, and flushes changes to the database. * * @param domainObject */ @Programmatic void removeAndFlush(Object domainObject); /** * Returns all the instances of the specified type (including subtypes). * If the optional range parameters are used, the dataset returned starts * from (0 based) index, and consists of only up to count items. * * <p> * If there are no instances the list will be empty. This method creates a * new {@link List} object each time it is called so the caller is free to * use or modify the returned {@link List}, but the changes will not be * reflected back to the repository. * </p> * * <p> * This method should only be called where the number of instances is known * to be relatively low, unless the optional range parameters (2 longs) are * specified. The range parameters are "start" and "count". * </p> * * @param range 2 longs, specifying 0-based start and count. */ @Programmatic <T> List<T> allInstances(Class<T> ofType, long... range); /** * Returns all the instances of the specified type (including subtypes) that * the predicate object accepts. If the optional range parameters are used, the * dataset returned starts from (0 based) index, and consists of only up to * count items. * * <p> * If there are no instances the list will be empty. This method creates a * new {@link List} object each time it is called so the caller is free to * use or modify the returned {@link List}, but the changes will not be * reflected back to the repository. * </p> * * <p> * This method is useful during exploration/prototyping, but - because the filtering is performed client-side - * this method is only really suitable for initial development/prototyping, or for classes with very few * instances. Use {@link #allMatches(Query)} for production code. * </p> * * @see #allMatches(Class, Predicate, long...) * * @param range 2 longs, specifying 0-based start and count. */ @Programmatic <T> List<T> allMatches(final Class<T> ofType, final Predicate<? super T> predicate, long... range); /** * Returns all the instances that match the given {@link Query}. * * <p> * If there are no instances the list will be empty. This method creates a * new {@link List} object each time it is called so the caller is free to * use or modify the returned {@link List}, but the changes will not be * reflected back to the repository. * </p> * * <p> * This method is the recommended way of querying for multiple instances. * </p> */ @Programmatic <T> List<T> allMatches(Query<T> query); /** * Returns the first instance of the specified type (including subtypes) * that matches the supplied {@link Predicate}, or <tt>null</tt> if none. * * <p> * This method is useful during exploration/prototyping, but - because the filtering is performed client-side - * this method is only really suitable for initial development/prototyping, or for classes with very few * instances. Use {@link #firstMatch(Query)} for production code. * </p> */ @Programmatic <T> T firstMatch(final Class<T> ofType, final Predicate<T> predicate); /** * Returns the first instance that matches the supplied query, or <tt>null</tt> if none. * * <p> * This method is the recommended way of querying for an instance when one or more may match. See also * {@link #uniqueMatch(Query)}. * </p> * * @see #uniqueMatch(Query) */ @Programmatic <T> T firstMatch(Query<T> query); /** * Find the only instance of the specified type (including subtypes) that * has the specified title. * * <p> * If no instance is found then <tt>null</tt> will be return, while if there * is more that one instances a run-time exception will be thrown. * * <p> * This method is useful during exploration/prototyping, but - because the filtering is performed client-side - * this method is only really suitable for initial development/prototyping, or for classes with very few * instances. Use {@link #uniqueMatch(Query)} for production code. * </p> */ @Programmatic <T> T uniqueMatch(final Class<T> ofType, final Predicate<T> predicate); /** * Find the only instance that matches the provided query. * * <p> * If no instance is found then null will be return, while if there is more * that one instances a run-time exception will be thrown. * </p> * * <p> * This method is the recommended way of querying for (precisely) one instance. See also {@link #firstMatch(Query)} * for less strict querying. * </p> * * @see #firstMatch(Query) */ @Programmatic <T> T uniqueMatch(Query<T> query); }