Files
jenkins/core/src/main/java/hudson/BulkChange.java
T
Josh Soref 496703d0fe Spelling fixes in changelogs, Javadoc, logs and UI (#2718)
* spelling: abstract

* spelling: about

* spelling: absolute

* spelling: across

* spelling: activity

* spelling: actually

* spelling: addition

* spelling: allocating

* spelling: ambiguous

* spelling: analyzes

* spelling: analysis

* spelling: another

* spelling: appear

* spelling: arbitrary

* spelling: artifact

* spelling: assignment

* spelling: associated

* spelling: augment

* spelling: authentication

* spelling: automatically

* spelling: available

* spelling: availability

* spelling: because

* spelling: background

* spelling: beginning

* spelling: boolean

* spelling: browsers

* spelling: building

* spelling: calculation

* spelling: channel

* spelling: column

* spelling: concatenation

* spelling: connect

* spelling: contribute

* spelling: convert

* spelling: copied

* spelling: couldn't

* spelling: scrambled

* spelling: creates-a

* spelling: curr-entry

* spelling: customize

* spelling: diagnostic

* spelling: contain

* spelling: default

* spelling: delimiter

* spelling: descriptor

* spelling: disambiguates

* spelling: different

* spelling: diligently

* spelling: disabled

* spelling: discovered

* spelling: display

* spelling: doesn't

* spelling: dollar

* spelling: downstream

* spelling: dynamically

* spelling: preemptively

* spelling: encrypt

* spelling: erroneous

* spelling: examine

* spelling: existence

* spelling: value

* spelling: february

* spelling: handling

* spelling: hostname

* spelling: convenient

* spelling: identify

* spelling: implementation

* spelling: incorrect

* spelling: individual

* spelling: initialization

* spelling: initialized

* spelling: inputstream

* spelling: instantiated

* spelling: instantiation

* spelling: intended

* spelling: interpreted

* spelling: interrupted

* spelling: invocations

* spelling: kern

* spelling: localization

* spelling: logger

* spelling: malfunctioning

* spelling: methods

* spelling: monitor

* spelling: mutator

* spelling: multiple

* spelling: object

* spelling: configured

* spelling: optionally

* spelling: option

* spelling: overridden

* spelling: parameterized

* spelling: parent

* spelling: permissions

* spelling: plugin

* spelling: potentially

* spelling: preferable

* spelling: problems like

* spelling: programmatically

* spelling: property

* spelling: reallocate

* spelling: recommended

* spelling: redirected

* spelling: registered

* spelling: reliable

* spelling: remember

* spelling: recurrence

* spelling: repeatable

* spelling: repeated

* spelling: resource

* spelling: retrieve

* spelling: returned

* spelling: revision

* spelling: sandwich

* spelling: separator

* spelling: serialization

* spelling: settings

* spelling: shadow

* spelling: should

* spelling: someone

* spelling: source

* spelling: specified

* spelling: style

* spelling: subversion

* spelling: sufficient

* spelling: supplementary

* spelling: suppressing

* spelling: synchronization

* spelling: synchronized

* spelling: this

* spelling: transitioning

* spelling: termination

* spelling: trying

* spelling: truncatable

* spelling: unknown

* spelling: undeployed

* spelling: unnecessary

* spelling: unparseable

* spelling: update

* spelling: upper

* spelling: verify

* spelling: visible

* spelling: warning

* spelling: we're

* spelling: whitespace

* spelling: wide

* spelling: with

* spelling: workspace

* spelling: yielding

* spelling: to

* spelling: by

* spelling: the

* spelling: hours
2017-02-12 13:38:30 +03:00

168 lines
5.3 KiB
Java

/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson;
import hudson.model.Saveable;
import java.io.Closeable;
import java.io.IOException;
/**
* Transaction-like object that can be used to make a bunch of changes to an object, and defer the
* {@link Saveable#save()} until the end.
*
* <p>
* The usage of {@link BulkChange} needs to follow a specific closure-like pattern, namely:
*
* <pre>
* try (BulkChange bc = new BulkChange(someObject)) {
* ... make changes to 'someObject'
* bc.commit();
* }
* </pre>
*
* <p>
* Use of this method is optional. If {@link BulkChange} is not used, individual mutator
* will perform the save operation, and things will just run somewhat slower.
*
*
* <h2>Cooperation from {@link Saveable}</h2>
* <p>
* For this class to work as intended, {@link Saveable} implementations need to co-operate.
* Namely,
*
* <ol>
* <li>
* Mutator methods should invoke {@code this.save()} so that if the method is called outside
* a {@link BulkChange}, the result will be saved immediately.
*
* <li>
* In the {@code save()} method implementation, use {@link #contains(Saveable)} and
* only perform the actual I/O operation when this method returns false.
* </ol>
*
* <p>
* See {@link jenkins.model.Jenkins#save()} as an example if you are not sure how to implement {@link Saveable}.
*
* @author Kohsuke Kawaguchi
* @since 1.249
*/
public class BulkChange implements Closeable {
private final Saveable saveable;
public final Exception allocator;
private final BulkChange parent;
private boolean completed;
public BulkChange(Saveable saveable) {
this.parent = current();
this.saveable = saveable;
// remember who allocated this object in case
// someone forgot to call save() at the end.
allocator = new Exception();
// in effect at construction
INSCOPE.set(this);
}
/**
* Saves the accumulated changes.
*/
public void commit() throws IOException {
if(completed) return;
completed = true;
// move this object out of the scope first before save, or otherwise the save() method will do nothing.
pop();
saveable.save();
}
/**
* Alias for {@link #abort()} to make {@link BulkChange} auto-closeable.
*/
@Override
public void close() {
abort();
}
/**
* Exits the scope of {@link BulkChange} without saving the changes.
*
* <p>
* This can be used when a bulk change fails in the middle.
* Note that unlike a real transaction, this will not roll back the state of the object.
*
* <p>
* The abort method can be called after the commit method, in which case this method does nothing.
* This is so that {@link BulkChange} can be used naturally in the try/finally block.
*/
public void abort() {
if(completed) return;
completed = true;
pop();
}
private void pop() {
if(current()!=this)
throw new AssertionError("Trying to save BulkChange that's not in scope");
INSCOPE.set(parent);
}
/**
* {@link BulkChange}s that are effective currently.
*/
private static final ThreadLocal<BulkChange> INSCOPE = new ThreadLocal<BulkChange>();
/**
* Gets the {@link BulkChange} instance currently in scope for the current thread.
*/
public static BulkChange current() {
return INSCOPE.get();
}
/**
* Checks if the given {@link Saveable} is currently in the bulk change.
*
* <p>
* The expected usage is from the {@link Saveable#save()} implementation to check
* if the actual persistence should happen now or not.
*/
public static boolean contains(Saveable s) {
for(BulkChange b=current(); b!=null; b=b.parent)
if(b.saveable==s || b.saveable==ALL)
return true;
return false;
}
/**
* Magic {@link Saveable} instance that can make {@link BulkChange} veto
* all the save operations by making the {@link #contains(Saveable)} method return
* true for everything.
*/
public static final Saveable ALL = new Saveable() {
public void save() {
}
};
}