]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RemoverUtil.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / RemoverUtil.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.layer0.util;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21 import java.util.TreeSet;
22
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.WriteGraph;
26 import org.simantics.db.common.CommentMetadata;
27 import org.simantics.db.common.request.UniqueRead;
28 import org.simantics.db.common.request.WriteRequest;
29 import org.simantics.db.common.request.WriteResultRequest;
30 import org.simantics.db.common.utils.NameUtils;
31 import org.simantics.db.exception.DatabaseException;
32 import org.simantics.db.layer0.adapter.Remover;
33 import org.simantics.db.layer0.adapter.impl.AbstractRemover;
34 import org.simantics.db.layer0.adapter.impl.EntityRemover;
35 import org.simantics.db.layer0.exception.CannotRemoveException;
36 import org.simantics.db.layer0.internal.SimanticsInternal;
37 import org.simantics.utils.strings.AlphanumComparator;
38 import org.simantics.utils.strings.EString;
39
40 /**
41  * Utility for working with {@link Remover}s.
42  * 
43  * @author Tuukka Lehtonen
44  * 
45  * @see Remover
46  * @see AbstractRemover
47  */
48 public final class RemoverUtil {
49
50         public static boolean canRemove(ReadGraph graph, Resource resource) throws DatabaseException {
51         Remover remover = RemoverUtil.getPossibleRemover(graph, resource);
52         if (remover != null) {
53             String problem = remover.canRemove(graph, new HashMap<Object, Object>(4));
54             if (problem != null) return false;
55         }
56         return true;
57         }
58         
59     public static void remove(WriteGraph graph, Resource resource) throws DatabaseException {
60         if (!tryRemover(graph, resource))
61             EntityRemover.remove(graph, resource, true);
62     }
63
64     public static boolean tryRemover(WriteGraph graph, Resource resource) throws DatabaseException {
65         Remover remover = getPossibleRemover(graph, resource);
66         if (remover != null) {
67             remover.remove(graph);
68             return true;
69         }
70         return false;
71     }
72
73     /**
74      * @param graph
75      * @param resource
76      * @return
77      * @throws DatabaseException
78      * @since 1.6
79      */
80     public static Remover getPossibleRemover(ReadGraph graph, Resource resource) throws DatabaseException {
81         return graph.getPossibleAdapter(resource, Remover.class);
82     }
83
84     public static String testRemoval(final Collection<Resource> rs) throws DatabaseException {
85         return SimanticsInternal.getSession().syncRequest(new UniqueRead<String>() {
86             @Override
87             public String perform(ReadGraph graph) throws DatabaseException {
88                 return testRemoval(graph, rs, null);
89             }
90         });
91     }
92
93     public static String testRemoval(ReadGraph graph, final Collection<Resource> rs, List<Remover> removers) throws DatabaseException {
94         if (removers == null)
95             removers = new ArrayList<Remover>(rs.size());
96
97         for (Resource r : rs) {
98             Remover remover = graph.getPossibleAdapter(r, Remover.class);
99             if (remover != null)
100                 removers.add(remover);
101         }
102
103         Map<Object, Object> aux = new HashMap<Object, Object>();
104         List<String> errors = new ArrayList<String>(2);
105         for (Remover remover : removers) {
106             String error = remover.canRemove(graph, aux);
107             if (error != null)
108                 errors.add(error);
109         }
110         if (!errors.isEmpty()) {
111             return EString.implode(errors);
112         }
113
114         return null;
115     }
116
117     public static String testRemoval(ReadGraph graph, final Collection<Resource> rs) throws DatabaseException {
118         return testRemoval(graph, rs, null);
119     }
120
121     public static String checkedRemoval(final Collection<Resource> rs) throws DatabaseException {
122         String problems = testRemoval(rs);
123         if (problems != null) return problems; 
124
125         SimanticsInternal.getSession().syncRequest(new WriteRequest() {
126
127             @Override
128             public void perform(WriteGraph graph) throws DatabaseException {
129                 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
130                 for (Resource r : rs) {
131                     // Add comment to change set.
132                     graph.addMetadata(cm.add("Removing " + r + "."));
133                 }
134
135                 List<Remover> removers = new ArrayList<Remover>(rs.size());
136                 String error = testRemoval(graph, rs, removers);
137                 if (error != null)
138                     throw new CannotRemoveException(error);
139
140                 for (Remover remover : removers)
141                     remover.remove(graph);
142             }
143
144         });
145
146         return null;
147     }
148
149     /**
150      * Try to remove the provided collection of resources. Removal will commence
151      * only if all resources in the provided collection have the exact same
152      * principal types.
153      * 
154      * @param rs
155      *            collection of resources to remove in one go
156      * @return <code>true</code> if removal was successful or <code>false</code>
157      *         if the principal types of all resources in the provided
158      *         collection did not match
159      * @throws CannotRemoveException
160      *             if removal cannot commence because at least one of the
161      *             {@link Remover} instances adapted from the provided resource
162      *             set succeeds.
163      * @throws DatabaseException
164      */
165     public static boolean tryCollectionRemover(final Collection<Resource> rs) throws DatabaseException {
166         return SimanticsInternal.getSession().syncRequest(new WriteResultRequest<Boolean>() {
167             @Override
168             public Boolean perform(WriteGraph graph) throws DatabaseException {
169                 graph.markUndoPoint();
170                 // 1. make sure that all resources are of the same type
171                 Collection<Resource> principalTypes = null;
172                 for (Resource r : rs) {
173                     Collection<Resource> pts = graph.getPrincipalTypes(r);
174                     if (principalTypes == null) {
175                         principalTypes = pts;
176                     } else if (!principalTypes.equals(pts)) {
177                         //return false;
178                         StringBuilder sb = new StringBuilder();
179                         sb.append("Removing resources of different types at the same time is currently not supported.\n\nThe selection contained resources of the following types:\n");
180                         Set<Resource> differentTypes = new HashSet<Resource>();
181                         Set<String> typeNames = new TreeSet<String>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);
182                         for (Resource t : rs)
183                             differentTypes.addAll(graph.getPrincipalTypes(t));
184                         for (Resource t : differentTypes)
185                             typeNames.add(NameUtils.getSafeName(graph, t));
186                         for (String typeName : typeNames)
187                             sb.append("\t").append(typeName).append("\n");
188                         throw new CannotRemoveException(sb.toString());
189                     }
190                 }
191
192                 List<Remover> removers = new ArrayList<Remover>();
193                 Map<Remover, String> removedResources = new HashMap<Remover, String>();
194                 for (Resource r : rs) {
195                     Remover remover = graph.getPossibleAdapter(r, Remover.class);
196                     if (remover != null) {
197                         removers.add(remover);
198                         removedResources.put(remover, NameUtils.getSafeName(graph, r, true));
199                     }
200                 }
201
202                 Map<Object, Object> aux = new HashMap<Object, Object>();
203                 List<String> errors = new ArrayList<String>(removers.size());
204                 for (Remover remover : removers) {
205                     String error = remover.canRemove(graph, aux);
206                     if (error != null)
207                         errors.add(error);
208                 }
209                 if (!errors.isEmpty()) {
210                     throw new CannotRemoveException(EString.implode(errors));
211                 }
212
213                 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
214                 for (Remover remover : removers) {
215                     remover.remove(graph);
216                     graph.addMetadata(cm.add("Removed " + removedResources.get(remover) + "."));
217                 }
218
219                 return true;
220             }
221         });
222     }
223
224 }