~ubuntu-branches/debian/sid/eclipse-cdt/sid

« back to all changes in this revision

Viewing changes to dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/properties/PropertiesUpdateStatus.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2011-10-06 21:15:04 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20111006211504-8dutmljjih0zikfv
Tags: 8.0.1-1
* New upstream release.
* Split the JNI packages into a separate architecture dependent
  package and made eclipse-cdt architecture independent.
* Install JNI libraries into multiarch aware location
* Bumped Standards-Version to 3.9.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2010 Wind River Systems and others.
 
3
 * All rights reserved. This program and the accompanying materials
 
4
 * are made available under the terms of the Eclipse Public License v1.0
 
5
 * which accompanies this distribution, and is available at
 
6
 * http://www.eclipse.org/legal/epl-v10.html
 
7
 * 
 
8
 * Contributors:
 
9
 *     Wind River Systems - initial API and implementation
 
10
 *******************************************************************************/
 
11
package org.eclipse.cdt.dsf.ui.viewmodel.properties;
 
12
 
 
13
import java.util.Collection;
 
14
import java.util.HashMap;
 
15
import java.util.HashSet;
 
16
import java.util.Map;
 
17
import java.util.Set;
 
18
 
 
19
import org.eclipse.cdt.dsf.concurrent.DsfMultiStatus;
 
20
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
 
21
import org.eclipse.core.runtime.IStatus;
 
22
 
 
23
/**
 
24
 * Status object for use with the IPropertiesUpdate.  This status class
 
25
 * allows setting a different status result for each property.  This allows
 
26
 * for better interpretation of status by the client of the update.
 
27
 * <p>
 
28
 * This status class derives from MultiStatus class such that the status 
 
29
 * objects for each property can be accessed through the standard 
 
30
 * {@link #getChildren()} method.  Also, multiple properties can reference 
 
31
 * the same status object, meaning that the number of properties returned
 
32
 * by {@link #getProperties()} may be greater than the status objects 
 
33
 * returned by <code>getChildren()</code>.
 
34
 * <p>
 
35
 * The properties status object does not have its own message, severity, 
 
36
 * error status or exception.  All these attributes are calculated from 
 
37
 * the child status objects.  If the status has more than one status child, 
 
38
 * the String returned by {@link #getMessage()} is: "Multiple errors reported".
 
39
 * 
 
40
 * @since 2.2
 
41
 */
 
42
public class PropertiesUpdateStatus extends DsfMultiStatus {
 
43
 
 
44
    final private Map<String,IStatus> fPropertiesStatus = new HashMap<String, IStatus>(1);
 
45
    private boolean fFirstStatusSet;
 
46
    
 
47
    public PropertiesUpdateStatus() {
 
48
        super(DsfUIPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
 
49
    }
 
50
    
 
51
    /**
 
52
     * Returns set of properties that have an additional status specified.
 
53
     */
 
54
    public Set<String> getProperties() {
 
55
        return fPropertiesStatus.keySet();
 
56
    }
 
57
    
 
58
    /**
 
59
     * Returns an additional status for the given property in a property 
 
60
     * update.  Returned value may be <code>null</code> if no additional
 
61
     * status is given.
 
62
     */
 
63
    public IStatus getStatus(String property) {
 
64
        return fPropertiesStatus.get(property);
 
65
    }
 
66
 
 
67
    /**
 
68
     * Sets the given status for the given property.
 
69
     */
 
70
    public void setStatus(String property, IStatus status) {
 
71
        IStatus child = findEquivalentChild(status);
 
72
        if (child != null) {
 
73
            status = child;
 
74
        } else {
 
75
            add(status);
 
76
        }
 
77
 
 
78
        fPropertiesStatus.put(property, status);
 
79
    }
 
80
 
 
81
    /**
 
82
     * Sets the given status for the properties array.
 
83
     */
 
84
    public void setStatus(String[] properties, IStatus status) {
 
85
        IStatus child = findEquivalentChild(status);
 
86
        if (child != null) {
 
87
            status = child;
 
88
        } else {
 
89
            add(status);
 
90
        }
 
91
 
 
92
        for (String property : properties) {
 
93
            fPropertiesStatus.put(property, status);
 
94
        }
 
95
    }
 
96
 
 
97
    /**
 
98
     * Merges data in the new status into the base status data, and returns the 
 
99
     * resulting status. Only properties specified in the given set are merged.
 
100
     * <p>
 
101
     * The new status is considered to be more up to date than the base 
 
102
     * status and its data overrides the base status .  If the base status 
 
103
     * holds an error for a given property, which is found in the 
 
104
     * given set, and the new status does not, then the base error status is 
 
105
     * removed. 
 
106
     *
 
107
     * @param baseStatus Properties into which the new status properties will 
 
108
     * be merged. 
 
109
     * @param newStatus Properties status to merge. 
 
110
     * @param properties The properties to consider in the new status.
 
111
     * @return Resulting merged status object. 
 
112
     */
 
113
    public static PropertiesUpdateStatus mergePropertiesStatus(PropertiesUpdateStatus baseStatus, 
 
114
        PropertiesUpdateStatus newStatus, Set<String> properties) 
 
115
    {
 
116
        PropertiesUpdateStatus mergedStatus = new PropertiesUpdateStatus();
 
117
        // Copy the property status map from the base status.
 
118
        mergedStatus.fPropertiesStatus.putAll(baseStatus.fPropertiesStatus);
 
119
        
 
120
        // Add in the property statuses from the new status, but only for the 
 
121
        // specified properties.
 
122
        for (String property : properties) {
 
123
            IStatus propertyStatus = newStatus.getStatus(property);
 
124
            if (propertyStatus != null) {
 
125
                mergedStatus.fPropertiesStatus.put(property, propertyStatus);
 
126
            } else {
 
127
                mergedStatus.fPropertiesStatus.remove(property);
 
128
            }
 
129
        }
 
130
 
 
131
        // Children of merged status should contain all statuses that are found in the fPropertiesStatus map, but 
 
132
        // without duplicates.
 
133
        Set<IStatus> children = new HashSet<IStatus>((baseStatus.getChildren().length + newStatus.getChildren().length) * 4/3);
 
134
        children.addAll(mergedStatus.fPropertiesStatus.values());
 
135
        for (IStatus child : children) {
 
136
            mergedStatus.add(child);
 
137
        }
 
138
 
 
139
        // Merged status should contain all children statuses that were added without a corresponding property to the 
 
140
        // base status and to the new status. 
 
141
        Collection<IStatus> baseStatusPropertyChildren = baseStatus.fPropertiesStatus.values();
 
142
        for (IStatus baseStatusChild : baseStatus.getChildren()) {
 
143
            if (!baseStatusPropertyChildren.contains(baseStatusChild)) {
 
144
                mergedStatus.add(baseStatusChild);
 
145
            }
 
146
        }
 
147
        Collection<IStatus> newStatusPropertyChildren = newStatus.fPropertiesStatus.values();
 
148
        for (IStatus newStatusChild : newStatus.getChildren()) {
 
149
            if (!newStatusPropertyChildren.contains(newStatusChild)) {
 
150
                mergedStatus.add(newStatusChild);
 
151
            }
 
152
        }
 
153
        
 
154
        return mergedStatus;
 
155
    }
 
156
    
 
157
    /**
 
158
     * Adds the given status object as a child of this status.  If there's an
 
159
     * equivalent child status already, the new status is ignored.
 
160
     */
 
161
    @Override
 
162
    public void add(IStatus status) {
 
163
        if (findEquivalentChild(status) != null) {
 
164
            return;
 
165
        }
 
166
        
 
167
        super.add(status);
 
168
 
 
169
        boolean firstSet;
 
170
        synchronized(this) {
 
171
            firstSet = fFirstStatusSet;
 
172
            fFirstStatusSet = true;
 
173
        }
 
174
        
 
175
        if (!firstSet) {
 
176
            setMessage(status.getMessage());
 
177
        } else {
 
178
            setMessage(MessagesForProperties.PropertiesUpdateStatus_message);
 
179
        }        
 
180
    }
 
181
    
 
182
    /**
 
183
     * Finds a child status that is equivalent to the given status.
 
184
     */
 
185
    private IStatus findEquivalentChild(IStatus status) {
 
186
        if (getChildren().length != 0) {
 
187
            for (IStatus child : getChildren()) {
 
188
                if (areEquivalent(child, status)) {
 
189
                    return child;
 
190
                }
 
191
            }
 
192
        }
 
193
        return null;
 
194
    }    
 
195
    
 
196
    /**
 
197
     * Compares two status objects to determine if they are equivalent.
 
198
     */
 
199
    private boolean areEquivalent(IStatus s1, IStatus s2) {
 
200
        if ( (s1 == null && s2 != null) || (s1 != null && s2 == null) ) 
 
201
        {
 
202
            return false;
 
203
        }
 
204
        if (s1 == null) {
 
205
            return true;
 
206
        }
 
207
        if ( (s1.getSeverity() != s2.getSeverity()) ||
 
208
             !s1.getPlugin().equals(s2.getPlugin()) ||
 
209
             (s1.getCode() != s2.getCode()) )
 
210
        {
 
211
            return false;
 
212
        }
 
213
        if ( (s1.getException() == null && s1.getException() != null) ||
 
214
             (s1.getException() != null && s1.getException() == null) ||
 
215
             (s1.getException() != null && !s1.getException().equals(s2.getException())) )
 
216
        {
 
217
            return false;
 
218
        }
 
219
        return s1.getMessage().equals(s2.getMessage());
 
220
    };
 
221
 
 
222
    /**
 
223
     * Convenience method that returns and optionally creates a properties 
 
224
     * update status object for the given update.
 
225
     */
 
226
    public static PropertiesUpdateStatus getPropertiesStatus(IPropertiesUpdate update) {
 
227
        IStatus updateStatus = update.getStatus();
 
228
        if (updateStatus instanceof PropertiesUpdateStatus) {
 
229
            return (PropertiesUpdateStatus)updateStatus; 
 
230
        } else {
 
231
            PropertiesUpdateStatus propertiesStatus = new PropertiesUpdateStatus(); 
 
232
            update.setStatus(propertiesStatus);
 
233
            if (!updateStatus.isOK()) {
 
234
                propertiesStatus.add(updateStatus);
 
235
            }
 
236
            return propertiesStatus;
 
237
        }
 
238
    }
 
239
    
 
240
    /**
 
241
     * Convenience method that returns and optionally creates a properties 
 
242
     * update status object for the given update.
 
243
     */
 
244
    public static PropertiesUpdateStatus makePropertiesStatus(IStatus updateStatus) {
 
245
        if (updateStatus instanceof PropertiesUpdateStatus) {
 
246
            return (PropertiesUpdateStatus)updateStatus; 
 
247
        } else {
 
248
            PropertiesUpdateStatus propertiesStatus = new PropertiesUpdateStatus(); 
 
249
            if (!updateStatus.isOK()) {
 
250
                propertiesStatus.add(updateStatus);
 
251
            }
 
252
            return propertiesStatus;
 
253
        }
 
254
    }
 
255
}