Ignore:
Timestamp:
2018-02-18T05:02:23+01:00 (21 months ago)
Author:
Don-vip
Message:

see #8039, see #10456 - support read-only data layers

Location:
trunk/src/org/openstreetmap/josm/data
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r13420 r13434  
    1717import java.util.Set;
    1818import java.util.concurrent.CopyOnWriteArrayList;
     19import java.util.concurrent.atomic.AtomicBoolean;
    1920import java.util.concurrent.locks.Lock;
    2021import java.util.concurrent.locks.ReadWriteLock;
     
    103104 * @author imi
    104105 */
    105 public final class DataSet extends QuadBucketPrimitiveStore implements Data, ProjectionChangeListener {
     106public final class DataSet extends QuadBucketPrimitiveStore implements Data, ProjectionChangeListener, ReadOnly {
    106107
    107108    /**
     
    143144            return xmlFlag;
    144145        }
     146
     147        /**
     148         * Returns the {@code UploadPolicy} for the given <code>upload='...'</code> XML-attribute
     149         * @param xmlFlag <code>upload='...'</code> XML-attribute to convert
     150         * @return {@code UploadPolicy} value
     151         * @throws IllegalArgumentException for invalid values
     152         * @since 13434
     153         */
     154        public static UploadPolicy of(String xmlFlag) {
     155            for (UploadPolicy policy : values()) {
     156                if (policy.getXmlFlag().equalsIgnoreCase(xmlFlag)) {
     157                    return policy;
     158                }
     159            }
     160            throw new IllegalArgumentException(xmlFlag);
     161        }
    145162    }
    146163
     
    171188    private String name;
    172189    private UploadPolicy uploadPolicy;
     190    /** Flag used to know if the dataset should not be editable */
     191    private final AtomicBoolean isReadOnly = new AtomicBoolean(false);
    173192
    174193    private final ReadWriteLock lock = new ReentrantReadWriteLock();
     
    259278            version = copyFrom.version;
    260279            uploadPolicy = copyFrom.uploadPolicy;
     280            isReadOnly.set(copyFrom.isReadOnly.get());
    261281        } finally {
    262282            copyFrom.getReadLock().unlock();
     
    353373     *
    354374     * @param version the API version, i.e. "0.6"
     375     * @throws IllegalStateException if the dataset is read-only
    355376     */
    356377    public void setVersion(String version) {
     378        checkModifiable();
    357379        this.version = version;
    358380    }
     
    533555     *
    534556     * @param primitive the primitive.
     557     * @throws IllegalStateException if the dataset is read-only
    535558     */
    536559    @Override
    537560    public void addPrimitive(OsmPrimitive primitive) {
    538561        Objects.requireNonNull(primitive, "primitive");
     562        checkModifiable();
    539563        beginUpdate();
    540564        try {
     
    561585     *
    562586     * @param primitiveId the id of the primitive
     587     * @throws IllegalStateException if the dataset is read-only
    563588     */
    564589    public void removePrimitive(PrimitiveId primitiveId) {
     590        checkModifiable();
    565591        beginUpdate();
    566592        try {
     
    587613    @Override
    588614    protected void removePrimitive(OsmPrimitive primitive) {
     615        checkModifiable();
    589616        beginUpdate();
    590617        try {
     
    9981025     * @param node the node
    9991026     * @return The set of ways that have been modified
     1027     * @throws IllegalStateException if the dataset is read-only
    10001028     */
    10011029    public Set<Way> unlinkNodeFromWays(Node node) {
     1030        checkModifiable();
    10021031        Set<Way> result = new HashSet<>();
    10031032        beginUpdate();
     
    10251054     * @param primitive the primitive
    10261055     * @return The set of relations that have been modified
     1056     * @throws IllegalStateException if the dataset is read-only
    10271057     */
    10281058    public Set<Relation> unlinkPrimitiveFromRelations(OsmPrimitive primitive) {
     1059        checkModifiable();
    10291060        Set<Relation> result = new HashSet<>();
    10301061        beginUpdate();
     
    10591090     * @param referencedPrimitive the referenced primitive
    10601091     * @return The set of primitives that have been modified
     1092     * @throws IllegalStateException if the dataset is read-only
    10611093     */
    10621094    public Set<OsmPrimitive> unlinkReferencesToPrimitive(OsmPrimitive referencedPrimitive) {
     1095        checkModifiable();
    10631096        Set<OsmPrimitive> result = new HashSet<>();
    10641097        beginUpdate();
     
    11311164     * }
    11321165     * </pre>
     1166     * @see #endUpdate()
    11331167     */
    11341168    public void beginUpdate() {
     
    11381172
    11391173    /**
     1174     * Must be called after a previous call to {@link #beginUpdate()} to fire change events.
     1175     * <br>
     1176     * Typical usecase should look like this:
     1177     * <pre>
     1178     * ds.beginUpdate();
     1179     * try {
     1180     *   ...
     1181     * } finally {
     1182     *   ds.endUpdate();
     1183     * }
     1184     * </pre>
    11401185     * @see DataSet#beginUpdate()
    11411186     */
     
    12731318     * Removes all primitives from the dataset and resets the currently selected primitives
    12741319     * to the empty collection. Also notifies selection change listeners if necessary.
     1320     * @throws IllegalStateException if the dataset is read-only
    12751321     */
    12761322    @Override
    12771323    public void clear() {
     1324        checkModifiable();
    12781325        beginUpdate();
    12791326        try {
     
    12921339     * Marks all "invisible" objects as deleted. These objects should be always marked as
    12931340     * deleted when downloaded from the server. They can be undeleted later if necessary.
    1294      *
     1341     * @throws IllegalStateException if the dataset is read-only
    12951342     */
    12961343    public void deleteInvisible() {
     1344        checkModifiable();
    12971345        for (OsmPrimitive primitive:allPrimitives) {
    12981346            if (!primitive.isVisible()) {
     
    13141362     * @param from The source DataSet
    13151363     * @param progressMonitor The progress monitor
     1364     * @throws IllegalStateException if the dataset is read-only
    13161365     */
    13171366    public synchronized void mergeFrom(DataSet from, ProgressMonitor progressMonitor) {
    13181367        if (from != null) {
     1368            checkModifiable();
    13191369            new DataSetMerger(this, from).merge(progressMonitor);
    13201370            synchronized (from) {
     
    14021452        mappaintCacheIdx++;
    14031453    }
     1454
     1455    @Override
     1456    public void setReadOnly() {
     1457        if (!isReadOnly.compareAndSet(false, true)) {
     1458            Logging.warn("Trying to set readOnly flag on a readOnly dataset ", getName());
     1459        }
     1460    }
     1461
     1462    @Override
     1463    public void unsetReadOnly() {
     1464        if (!isReadOnly.compareAndSet(true, false)) {
     1465            Logging.warn("Trying to unset readOnly flag on a non-readOnly dataset ", getName());
     1466        }
     1467    }
     1468
     1469    @Override
     1470    public boolean isReadOnly() {
     1471        return isReadOnly.get();
     1472    }
     1473
     1474    /**
     1475     * Checks the dataset is modifiable (not read-only).
     1476     * @throws IllegalStateException if the dataset is read-only
     1477     */
     1478    private void checkModifiable() {
     1479        if (isReadOnly()) {
     1480            throw new IllegalStateException("DataSet is read-only");
     1481        }
     1482    }
    14041483}
  • trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java

    r13208 r13434  
    9898     */
    9999    public void executeFilters() {
    100         DataSet ds = Main.main.getEditDataSet();
     100        DataSet ds = Main.main.getActiveDataSet();
    101101        changed = false;
    102102        if (ds == null) {
  • trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

    r13420 r13434  
    275275    }
    276276
     277    /**
     278     * Throws exception if primitive is in a read-only dataset
     279     */
     280    protected final void checkDatasetNotReadOnly() {
     281        if (dataSet != null && dataSet.isReadOnly())
     282            throw new DataIntegrityProblemException("Primitive cannot be modified in read-only dataset: " + toString());
     283    }
     284
    277285    protected boolean writeLock() {
    278286        if (dataSet != null) {
     
    305313    @Override
    306314    public void setOsmId(long id, int version) {
     315        checkDatasetNotReadOnly();
    307316        boolean locked = writeLock();
    308317        try {
     
    343352    @Override
    344353    public void setUser(User user) {
     354        checkDatasetNotReadOnly();
    345355        boolean locked = writeLock();
    346356        try {
     
    353363    @Override
    354364    public void setChangesetId(int changesetId) {
     365        checkDatasetNotReadOnly();
    355366        boolean locked = writeLock();
    356367        try {
     
    367378    @Override
    368379    public void setTimestamp(Date timestamp) {
     380        checkDatasetNotReadOnly();
    369381        boolean locked = writeLock();
    370382        try {
     
    534546    @Override
    535547    public void setModified(boolean modified) {
     548        checkDatasetNotReadOnly();
    536549        boolean locked = writeLock();
    537550        try {
     
    548561    @Override
    549562    public void setVisible(boolean visible) {
     563        checkDatasetNotReadOnly();
    550564        boolean locked = writeLock();
    551565        try {
     
    559573    @Override
    560574    public void setDeleted(boolean deleted) {
     575        checkDatasetNotReadOnly();
    561576        boolean locked = writeLock();
    562577        try {
     
    577592    @Override
    578593    protected final void setIncomplete(boolean incomplete) {
     594        checkDatasetNotReadOnly();
    579595        boolean locked = writeLock();
    580596        try {
     
    891907    @Override
    892908    public final void setKeys(TagMap keys) {
     909        checkDatasetNotReadOnly();
    893910        boolean locked = writeLock();
    894911        try {
     
    901918    @Override
    902919    public final void setKeys(Map<String, String> keys) {
     920        checkDatasetNotReadOnly();
    903921        boolean locked = writeLock();
    904922        try {
     
    911929    @Override
    912930    public final void put(String key, String value) {
     931        checkDatasetNotReadOnly();
    913932        boolean locked = writeLock();
    914933        try {
     
    921940    @Override
    922941    public final void remove(String key) {
     942        checkDatasetNotReadOnly();
    923943        boolean locked = writeLock();
    924944        try {
     
    931951    @Override
    932952    public final void removeAll() {
     953        checkDatasetNotReadOnly();
    933954        boolean locked = writeLock();
    934955        try {
     
    966987     */
    967988    protected void addReferrer(OsmPrimitive referrer) {
     989        checkDatasetNotReadOnly();
    968990        if (referrers == null) {
    969991            referrers = referrer;
     
    9861008     */
    9871009    protected void removeReferrer(OsmPrimitive referrer) {
     1010        checkDatasetNotReadOnly();
    9881011        if (referrers instanceof OsmPrimitive) {
    9891012            if (referrers == referrer) {
     
    11481171     */
    11491172    public void mergeFrom(OsmPrimitive other) {
     1173        checkDatasetNotReadOnly();
    11501174        boolean locked = writeLock();
    11511175        try {
     
    12391263     */
    12401264    public void load(PrimitiveData data) {
     1265        checkDatasetNotReadOnly();
    12411266        // Write lock is provided by subclasses
    12421267        setKeys(data.hasKeys() ? data.getKeys() : null);
  • trunk/src/org/openstreetmap/josm/data/osm/Relation.java

    r13206 r13434  
    4646     */
    4747    public void setMembers(List<RelationMember> members) {
     48        checkDatasetNotReadOnly();
    4849        boolean locked = writeLock();
    4950        try {
     
    8889     */
    8990    public void addMember(RelationMember member) {
     91        checkDatasetNotReadOnly();
    9092        boolean locked = writeLock();
    9193        try {
     
    105107     */
    106108    public void addMember(int index, RelationMember member) {
     109        checkDatasetNotReadOnly();
    107110        boolean locked = writeLock();
    108111        try {
     
    127130     */
    128131    public RelationMember setMember(int index, RelationMember member) {
     132        checkDatasetNotReadOnly();
    129133        boolean locked = writeLock();
    130134        try {
     
    150154     */
    151155    public RelationMember removeMember(int index) {
     156        checkDatasetNotReadOnly();
    152157        boolean locked = writeLock();
    153158        try {
     
    376381     */
    377382    public void removeMembersFor(Collection<? extends OsmPrimitive> primitives) {
     383        checkDatasetNotReadOnly();
    378384        if (primitives == null || primitives.isEmpty())
    379385            return;
  • trunk/src/org/openstreetmap/josm/data/osm/Way.java

    r13206 r13434  
    5353     */
    5454    public void setNodes(List<Node> nodes) {
     55        checkDatasetNotReadOnly();
    5556        boolean locked = writeLock();
    5657        try {
     
    361362     */
    362363    public void removeNode(Node n) {
     364        checkDatasetNotReadOnly();
    363365        if (n == null || isIncomplete()) return;
    364366        boolean locked = writeLock();
     
    389391     */
    390392    public void removeNodes(Set<? extends Node> selection) {
     393        checkDatasetNotReadOnly();
    391394        if (selection == null || isIncomplete()) return;
    392395        boolean locked = writeLock();
     
    425428     */
    426429    public void addNode(Node n) {
     430        checkDatasetNotReadOnly();
    427431        if (n == null) return;
    428432
     
    452456     */
    453457    public void addNode(int offs, Node n) {
     458        checkDatasetNotReadOnly();
    454459        if (n == null) return;
    455460
  • trunk/src/org/openstreetmap/josm/data/osm/event/DatasetEventManager.java

    r12636 r13434  
    182182    @Override
    183183    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
    184         DataSet oldData = e.getPreviousEditDataSet();
     184        DataSet oldData = e.getPreviousDataSet();
    185185        if (oldData != null) {
    186186            oldData.removeDataSetListener(myListener);
    187187        }
    188188
    189         DataSet newData = e.getSource().getEditDataSet();
     189        DataSet newData = e.getSource().getActiveDataSet();
    190190        if (newData != null) {
    191191            newData.addDataSetListener(myListener);
  • trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java

    r13223 r13434  
    184184    @Override
    185185    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
    186         DataSet oldDataSet = e.getPreviousEditDataSet();
     186        DataSet oldDataSet = e.getPreviousDataSet();
    187187        if (oldDataSet != null) {
    188188            // Fake a selection removal
     
    194194            oldDataSet.removeSelectionListener(this);
    195195        }
    196         DataSet newDataSet = e.getSource().getEditDataSet();
     196        DataSet newDataSet = e.getSource().getActiveDataSet();
    197197        if (newDataSet != null) {
    198198            newDataSet.addSelectionListener(this);
  • trunk/src/org/openstreetmap/josm/data/projection/Projections.java

    r13423 r13434  
    320320                cproj.update(pd.definition);
    321321            } catch (ProjectionConfigurationException ex) {
    322                 throw new RuntimeException("Error loading " + code, ex);
     322                throw new JosmRuntimeException("Error loading " + code, ex);
    323323            }
    324324            proj = cproj;
  • trunk/src/org/openstreetmap/josm/data/validation/TestError.java

    r12390 r13434  
    1212
    1313import org.openstreetmap.josm.command.Command;
     14import org.openstreetmap.josm.data.osm.DataSet;
    1415import org.openstreetmap.josm.data.osm.Node;
    1516import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    358359     */
    359360    public boolean isFixable() {
    360         return fixingCommand != null || ((tester != null) && tester.isFixable(this));
     361        return (fixingCommand != null || ((tester != null) && tester.isFixable(this)))
     362                && primitives.stream().map(OsmPrimitive::getDataSet).noneMatch(DataSet::isReadOnly);
    361363    }
    362364
Note: See TracChangeset for help on using the changeset viewer.