1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.layer0.util;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.List;
20 import org.simantics.db.ReadGraph;
21 import org.simantics.db.Resource;
22 import org.simantics.db.WriteGraph;
23 import org.simantics.db.common.CommentMetadata;
24 import org.simantics.db.common.request.UniqueRead;
25 import org.simantics.db.common.request.WriteRequest;
26 import org.simantics.db.common.request.WriteResultRequest;
27 import org.simantics.db.common.utils.NameUtils;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.db.layer0.adapter.Remover;
30 import org.simantics.db.layer0.adapter.impl.AbstractRemover;
31 import org.simantics.db.layer0.adapter.impl.EntityRemover;
32 import org.simantics.db.layer0.exception.CannotRemoveException;
33 import org.simantics.db.layer0.internal.SimanticsInternal;
34 import org.simantics.utils.strings.EString;
37 * Utility for working with {@link Remover}s.
39 * @author Tuukka Lehtonen
42 * @see AbstractRemover
44 public final class RemoverUtil {
46 public static boolean canRemove(ReadGraph graph, Resource resource) throws DatabaseException {
47 Remover remover = RemoverUtil.getPossibleRemover(graph, resource);
48 if (remover != null) {
49 String problem = remover.canRemove(graph, new HashMap<>(4));
50 if (problem != null) return false;
55 public static void remove(WriteGraph graph, Resource resource) throws DatabaseException {
56 if (!tryRemover(graph, resource))
57 EntityRemover.remove(graph, resource, true);
60 public static boolean tryRemover(WriteGraph graph, Resource resource) throws DatabaseException {
61 Remover remover = getPossibleRemover(graph, resource);
62 if (remover != null) {
63 remover.remove(graph);
73 * @throws DatabaseException
76 public static Remover getPossibleRemover(ReadGraph graph, Resource resource) throws DatabaseException {
77 return graph.getPossibleAdapter(resource, Remover.class);
80 public static String testRemoval(final Collection<Resource> rs) throws DatabaseException {
81 return SimanticsInternal.getSession().syncRequest(new UniqueRead<String>() {
83 public String perform(ReadGraph graph) throws DatabaseException {
84 return testRemoval(graph, rs, null);
89 public static String testRemoval(ReadGraph graph, final Collection<Resource> rs, List<Remover> removers) throws DatabaseException {
91 removers = new ArrayList<>(rs.size());
93 for (Resource r : rs) {
94 Remover remover = graph.getPossibleAdapter(r, Remover.class);
96 removers.add(remover);
99 Map<Object, Object> aux = new HashMap<>();
100 List<String> errors = new ArrayList<>(2);
101 for (Remover remover : removers) {
102 String error = remover.canRemove(graph, aux);
106 if (!errors.isEmpty()) {
107 return EString.implode(errors);
113 public static String testRemoval(ReadGraph graph, final Collection<Resource> rs) throws DatabaseException {
114 return testRemoval(graph, rs, null);
117 public static String checkedRemoval(final Collection<Resource> rs) throws DatabaseException {
118 String problems = testRemoval(rs);
119 if (problems != null) return problems;
121 SimanticsInternal.getSession().syncRequest(new WriteRequest() {
124 public void perform(WriteGraph graph) throws DatabaseException {
125 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
126 for (Resource r : rs) {
127 // Add comment to change set.
128 graph.addMetadata(cm.add("Removing " + r + "."));
131 List<Remover> removers = new ArrayList<>(rs.size());
132 String error = testRemoval(graph, rs, removers);
134 throw new CannotRemoveException(error);
136 for (Remover remover : removers)
137 remover.remove(graph);
146 * Try to remove the provided collection of resources. Removal will commence
147 * only if all resources in the provided collection have the exact same
151 * collection of resources to remove in one go
152 * @return <code>true</code> if removal was successful or <code>false</code>
153 * if the principal types of all resources in the provided
154 * collection did not match
155 * @throws CannotRemoveException
156 * if removal cannot commence because at least one of the
157 * {@link Remover} instances adapted from the provided resource
159 * @throws DatabaseException
161 public static boolean tryCollectionRemover(final Collection<Resource> rs) throws DatabaseException {
162 return SimanticsInternal.getSession().syncRequest(new WriteResultRequest<Boolean>() {
164 public Boolean perform(WriteGraph graph) throws DatabaseException {
165 graph.markUndoPoint();
167 List<Remover> removers = new ArrayList<>();
168 Map<Remover, String> removedResources = new HashMap<>();
169 for (Resource r : rs) {
170 Remover remover = graph.getPossibleAdapter(r, Remover.class);
171 if (remover != null) {
172 removers.add(remover);
173 removedResources.put(remover, NameUtils.getSafeName(graph, r, true));
177 Map<Object, Object> aux = new HashMap<>();
178 List<String> errors = new ArrayList<>(removers.size());
179 for (Remover remover : removers) {
180 String error = remover.canRemove(graph, aux);
184 if (!errors.isEmpty()) {
185 throw new CannotRemoveException(EString.implode(errors));
188 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
189 for (Remover remover : removers) {
190 remover.remove(graph);
191 graph.addMetadata(cm.add("Removed " + removedResources.get(remover) + "."));