geforkt von Mirrors/FastAsyncWorldEdit
Merge branch 'master' into bukkit
Dieser Commit ist enthalten in:
Commit
0dfb88c41d
@ -1,3 +1,32 @@
|
||||
2.5:
|
||||
- Fixed issues with permissions not being read correctly.
|
||||
- WorldEdit is now world-aware (not that the Minecraft server is).
|
||||
- Abstracted super pickaxe mode/tools and changed commands to /tree, /info,
|
||||
/none, /single, /area, and /recur.
|
||||
- New /repl super pickaxe tool.
|
||||
- Now bundling JNBT.
|
||||
- Add a very rudimentary command line program that will check the integrity
|
||||
(a very basic integrity check) of a world.
|
||||
|
||||
2.4:
|
||||
- Added the ability to use (require) inventory with operations, preventing
|
||||
people from setting blocks that they don't have.
|
||||
- Simplified the max blocks change limit to be binary (either you have it or
|
||||
not). Also separated the 'max' limit and the 'default' limit in terms
|
||||
of configuration. This means that the WorldEdit restrictions file is
|
||||
no longer used.
|
||||
- A large part of the code was moved around (again) to make porting
|
||||
WorldEdit to other modding APIs easier, but this means that something
|
||||
may have broken.
|
||||
- Chest handling was rewritten for Minecraft beta, so it should be
|
||||
reliable now and not cause exceptions.
|
||||
- Item damage is now managed by WorldEdit's chest handling APIs.
|
||||
- Worked around an issue with the java.util.zip implementation that
|
||||
caused ZIP files containing backslashes to not work correctly.
|
||||
- Changed the TrueZip support to use the API for java.util.zip, meaning
|
||||
some bugs should be fixed.
|
||||
- Made all commands support double forward slashes as the command prefix.
|
||||
|
||||
2.3.4:
|
||||
- Fixed issues with chests.
|
||||
- Added configuration option that disables the "//" prefix and lets you use
|
||||
|
@ -5,7 +5,7 @@ This plugin requires Hey0's server modification.
|
||||
|
||||
1. Create a "plugins" folder inside your "bin" folder.
|
||||
|
||||
2. Copy WorldEdit.jar and jnbt.jar into "plugins".
|
||||
2. Copy WorldEdit.jar into "plugins".
|
||||
|
||||
3. Add "WorldEdit" to the "plugins" line of your server.properties file.
|
||||
If it's not already there, add the line. The line should look like this:
|
||||
|
26
LICENSE.txt
26
LICENSE.txt
@ -202,3 +202,29 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
|
||||
JOpt Simple License
|
||||
-------------------
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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.
|
||||
|
@ -2,3 +2,5 @@ This product includes software from JNBT (http://jnbt.sourceforge.net/).
|
||||
|
||||
This product includes software from WorldEdit
|
||||
(http://www.sk89q.com), under GNU Lesser General Public License, version 3.
|
||||
|
||||
This product includes software from JOpt Simple, under the MIT license.
|
11
build.xml
11
build.xml
@ -18,7 +18,6 @@
|
||||
<classpath>
|
||||
<fileset dir="${lib.dir}">
|
||||
<include name="truezip.jar" />
|
||||
<include name="jnbt.jar" />
|
||||
<include name="Minecraft_Mod.jar" />
|
||||
<include name="minecraft_server.jar" />
|
||||
<include name="Bukkit.jar" />
|
||||
@ -34,7 +33,8 @@
|
||||
<attribute name="Implementation-Title" value="WorldEdit"/>
|
||||
<attribute name="Implementation-Version" value="${version}"/>
|
||||
<attribute name="WorldEdit-Version" value="${version}"/>
|
||||
<attribute name="Class-Path" value="jnbt.jar truezip.jar"/>
|
||||
<attribute name="Class-Path" value="truezip.jar"/>
|
||||
<attribute name="Main-Class" value="com.sk89q.worldedit.cli.Main"/>
|
||||
</manifest>
|
||||
<copy tofile="${build.dir}/plugin.yml" file="plugin.yml"/>
|
||||
<jar jarfile="${dist.dir}/WorldEdit.jar" basedir="${build.dir}" manifest="manifest.mf"/>
|
||||
@ -59,17 +59,12 @@
|
||||
<copy tofile="${release.dir}/worldedit.updatr" file="worldedit.updatr"/>
|
||||
<replace file="${release.dir}/worldedit.updatr" token="%version%" value="${version}"/>
|
||||
<copy tofile="${release.dir}/WorldEdit.jar" file="${dist.dir}/WorldEdit.jar"/>
|
||||
<copy todir="${release.dir}">
|
||||
<fileset dir="lib">
|
||||
<include name="jnbt.jar"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<zip destfile="${release.dir}/worldedit-${version}.zip" basedir="${release.dir}" excludes="*.zip"/>
|
||||
<mkdir dir="${release.dir}/src"/>
|
||||
<copy todir="${release.dir}/src">
|
||||
<fileset dir="${src.dir}"/>
|
||||
</copy>
|
||||
<zip destfile="${release.dir}/worldedit-${version}-source.zip" basedir="${release.dir}" excludes="*.zip"/>
|
||||
<zip destfile="${release.dir}/worldedit-${version}-src.zip" basedir="${release.dir}" excludes="*.zip"/>
|
||||
</target>
|
||||
|
||||
<!-- Clean the output -->
|
||||
|
122
src/HMConfiguration.java
Normale Datei
122
src/HMConfiguration.java
Normale Datei
@ -0,0 +1,122 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LogFormat;
|
||||
import com.sk89q.worldedit.snapshots.SnapshotRepository;
|
||||
|
||||
/**
|
||||
* Configuration for hMod.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class HMConfiguration extends LocalConfiguration {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
|
||||
|
||||
/**
|
||||
* Properties file.
|
||||
*/
|
||||
private PropertiesFile properties;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*/
|
||||
public HMConfiguration() {
|
||||
properties = new PropertiesFile("worldedit.properties");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration.
|
||||
*/
|
||||
public void load() {
|
||||
try {
|
||||
properties.load();
|
||||
} catch (IOException e) {
|
||||
logger.warning("worldedit.properties could not be loaded: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
profile = properties.getBoolean("debug-profile", profile);
|
||||
wandItem = properties.getInt("wand-item", wandItem);
|
||||
defaultChangeLimit = Math.max(-1, properties.getInt(
|
||||
"default-max-blocks-changed", defaultChangeLimit));
|
||||
maxChangeLimit = Math.max(-1,
|
||||
properties.getInt("max-blocks-changed", maxChangeLimit));
|
||||
maxRadius = Math.max(-1, properties.getInt("max-radius", maxRadius));
|
||||
maxSuperPickaxeSize = Math.max(1, properties.getInt(
|
||||
"max-super-pickaxe-size", maxSuperPickaxeSize));
|
||||
registerHelp = properties.getBoolean("register-help", registerHelp);
|
||||
logComands = properties.getBoolean("log-commands", logComands);
|
||||
superPickaxeDrop = properties.getBoolean("super-pickaxe-drop-items",
|
||||
superPickaxeDrop);
|
||||
superPickaxeManyDrop = properties.getBoolean(
|
||||
"super-pickaxe-many-drop-items", superPickaxeManyDrop);
|
||||
noDoubleSlash = properties.getBoolean("no-double-slash", noDoubleSlash);
|
||||
useInventory = properties.getBoolean("use-inventory", useInventory);
|
||||
useInventoryOverride = properties.getBoolean("use-inventory-override",
|
||||
useInventoryOverride);
|
||||
|
||||
// Get disallowed blocks
|
||||
disallowedBlocks = new HashSet<Integer>();
|
||||
String defdisallowedBlocks = StringUtil.joinString(defaultDisallowedBlocks, ",", 0);
|
||||
for (String b : properties.getString("disallowed-blocks",
|
||||
defdisallowedBlocks).split(",")) {
|
||||
try {
|
||||
disallowedBlocks.add(Integer.parseInt(b));
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
String snapshotsDir = properties.getString("snapshots-dir", "");
|
||||
if (!snapshotsDir.trim().equals("")) {
|
||||
snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
} else {
|
||||
snapshotRepo = null;
|
||||
}
|
||||
|
||||
String type = properties.getString("shell-save-type", "").trim();
|
||||
shellSaveType = type.equals("") ? null : type;
|
||||
|
||||
String logFile = properties.getString("log-file", "");
|
||||
if (!logFile.equals("")) {
|
||||
try {
|
||||
FileHandler handler = new FileHandler(logFile, true);
|
||||
handler.setFormatter(new LogFormat());
|
||||
logger.addHandler(handler);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not use log file " + logFile + ": "
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
for (Handler handler : logger.getHandlers()) {
|
||||
logger.removeHandler(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,9 +17,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.ServerInterface;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditPlayer;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.WorldVector;
|
||||
import com.sk89q.worldedit.bags.BlockBag;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
|
||||
@ -27,7 +29,7 @@ import com.sk89q.worldedit.blocks.BlockType;
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class HMPlayer extends WorldEditPlayer {
|
||||
public class HMPlayer extends LocalPlayer {
|
||||
/**
|
||||
* Stores the player.
|
||||
*/
|
||||
@ -38,8 +40,8 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public HMPlayer(Player player) {
|
||||
super();
|
||||
public HMPlayer(ServerInterface server, Player player) {
|
||||
super(server);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@ -58,13 +60,13 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
* @param range
|
||||
* @return point
|
||||
*/
|
||||
public Vector getBlockTrace(int range) {
|
||||
public WorldVector getBlockTrace(int range) {
|
||||
HitBlox hitBlox = new HitBlox(player,range, 0.2);
|
||||
Block block = hitBlox.getTargetBlock();
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
return new Vector(block.getX(), block.getY(), block.getZ());
|
||||
return new WorldVector(null, block.getX(), block.getY(), block.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,7 +75,7 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
* @param range
|
||||
* @return point
|
||||
*/
|
||||
public Vector getSolidBlockTrace(int range) {
|
||||
public WorldVector getSolidBlockTrace(int range) {
|
||||
HitBlox hitBlox = new HitBlox(player,range, 0.2);
|
||||
Block block = null;
|
||||
|
||||
@ -85,14 +87,9 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
return new Vector(block.getX(), block.getY(), block.getZ());
|
||||
return new WorldVector(null, block.getX(), block.getY(), block.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the item that the player is holding.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/**
|
||||
* Get the ID of the item that the player is holding.
|
||||
*
|
||||
@ -111,11 +108,6 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
return player.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player's view pitch.
|
||||
*
|
||||
* @return pitch
|
||||
*/
|
||||
/**
|
||||
* Get the player's view pitch.
|
||||
*
|
||||
@ -130,15 +122,19 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
*
|
||||
* @return point
|
||||
*/
|
||||
public Vector getPosition() {
|
||||
return new Vector(player.getX(), player.getY(), player.getZ());
|
||||
public WorldVector getPosition() {
|
||||
return new WorldVector(null, player.getX(), player.getY(), player.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player's view yaw.
|
||||
* Get the player's world.
|
||||
*
|
||||
* @return yaw
|
||||
* @return point
|
||||
*/
|
||||
public LocalWorld getWorld() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player's view yaw.
|
||||
*
|
||||
@ -148,12 +144,6 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
return player.getRotation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the player an item.
|
||||
*
|
||||
* @param type
|
||||
* @param amt
|
||||
*/
|
||||
/**
|
||||
* Gives the player an item.
|
||||
*
|
||||
@ -174,6 +164,7 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
boolean foundNext = false;
|
||||
int searchDist = 0;
|
||||
HitBlox hitBlox = new HitBlox(player,range, 0.2);
|
||||
LocalWorld world = getPosition().getWorld();
|
||||
Block block;
|
||||
while ((block = hitBlox.getNextBlock()) != null) {
|
||||
searchDist++;
|
||||
@ -183,7 +174,7 @@ public class HMPlayer extends WorldEditPlayer {
|
||||
if (block.getType() == 0) {
|
||||
if (foundNext) {
|
||||
Vector v = new Vector(block.getX(), block.getY() - 1, block.getZ());
|
||||
if (server.getBlockType(v) == 0) {
|
||||
if (server.getBlockType(world, v) == 0) {
|
||||
setPosition(v.add(0.5, 0, 0.5));
|
||||
return true;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public boolean setBlockType(Vector pt, int type) {
|
||||
public boolean setBlockType(LocalWorld world, Vector pt, int type) {
|
||||
// Can't set colored cloth or crash
|
||||
if ((type >= 21 && type <= 34) || type == 36) {
|
||||
return false;
|
||||
@ -58,7 +58,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public int getBlockType(Vector pt) {
|
||||
public int getBlockType(LocalWorld world, Vector pt) {
|
||||
return etc.getServer().getBlockIdAt(pt.getBlockX(), pt.getBlockY(),
|
||||
pt.getBlockZ());
|
||||
}
|
||||
@ -70,7 +70,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public void setBlockData(Vector pt, int data) {
|
||||
public void setBlockData(LocalWorld world, Vector pt, int data) {
|
||||
etc.getServer().setBlockData(pt.getBlockX(), pt.getBlockY(),
|
||||
pt.getBlockZ(), data);
|
||||
}
|
||||
@ -81,7 +81,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public int getBlockData(Vector pt) {
|
||||
public int getBlockData(LocalWorld world, Vector pt) {
|
||||
return etc.getServer().getBlockData(pt.getBlockX(), pt.getBlockY(),
|
||||
pt.getBlockZ());
|
||||
}
|
||||
@ -92,7 +92,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @param text
|
||||
*/
|
||||
public void setSignText(Vector pt, String[] text) {
|
||||
public void setSignText(LocalWorld world, Vector pt, String[] text) {
|
||||
Sign signData = (Sign)etc.getServer().getComplexBlock(
|
||||
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
if (signData == null) {
|
||||
@ -110,7 +110,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public String[] getSignText(Vector pt) {
|
||||
public String[] getSignText(LocalWorld world, Vector pt) {
|
||||
Sign signData = (Sign)etc.getServer().getComplexBlock(
|
||||
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
if (signData == null) {
|
||||
@ -130,7 +130,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public BaseItemStack[] getChestContents(Vector pt) {
|
||||
public BaseItemStack[] getChestContents(LocalWorld world, Vector pt) {
|
||||
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
|
||||
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
|
||||
@ -165,7 +165,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param contents
|
||||
* @return
|
||||
*/
|
||||
public boolean setChestContents(Vector pt,
|
||||
public boolean setChestContents(LocalWorld world, Vector pt,
|
||||
BaseItemStack[] contents) {
|
||||
|
||||
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
|
||||
@ -197,7 +197,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public boolean clearChest(Vector pt) {
|
||||
public boolean clearChest(LocalWorld world, Vector pt) {
|
||||
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
|
||||
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
|
||||
@ -247,7 +247,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @param mobType
|
||||
*/
|
||||
public void setMobSpawnerType(Vector pt, String mobType) {
|
||||
public void setMobSpawnerType(LocalWorld world, Vector pt, String mobType) {
|
||||
ComplexBlock cblock = etc.getServer().getComplexBlock(
|
||||
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
|
||||
@ -266,7 +266,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @param mobType
|
||||
*/
|
||||
public String getMobSpawnerType(Vector pt) {
|
||||
public String getMobSpawnerType(LocalWorld world, Vector pt) {
|
||||
try {
|
||||
return MinecraftServerInterface.getMobSpawnerType(pt);
|
||||
} catch (Throwable t) {
|
||||
@ -282,7 +282,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public boolean generateTree(EditSession editSession, Vector pt) {
|
||||
public boolean generateTree(EditSession editSession, LocalWorld world, Vector pt) {
|
||||
try {
|
||||
return MinecraftServerInterface.generateTree(editSession, pt);
|
||||
} catch (Throwable t) {
|
||||
@ -300,7 +300,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param count
|
||||
* @param times
|
||||
*/
|
||||
public void dropItem(Vector pt, int type, int count, int times) {
|
||||
public void dropItem(LocalWorld world, Vector pt, int type, int count, int times) {
|
||||
for (int i = 0; i < times; i++) {
|
||||
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
|
||||
type, count);
|
||||
@ -315,7 +315,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param count
|
||||
* @param times
|
||||
*/
|
||||
public void dropItem(Vector pt, int type, int count) {
|
||||
public void dropItem(LocalWorld world, Vector pt, int type, int count) {
|
||||
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
|
||||
type, count);
|
||||
}
|
||||
@ -328,7 +328,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param count
|
||||
* @param times
|
||||
*/
|
||||
public void dropItem(Vector pt, int type) {
|
||||
public void dropItem(LocalWorld world, Vector pt, int type) {
|
||||
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
|
||||
type, 1);
|
||||
}
|
||||
@ -338,57 +338,57 @@ public class HMServerInterface extends ServerInterface {
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public void simulateBlockMine(Vector pt) {
|
||||
int type = getBlockType(pt);
|
||||
setBlockType(pt, 0);
|
||||
public void simulateBlockMine(LocalWorld world, Vector pt) {
|
||||
int type = getBlockType(world, pt);
|
||||
//setBlockType(world, pt, 0);
|
||||
|
||||
if (type == 1) { dropItem(pt, 4); } // Stone
|
||||
else if (type == 2) { dropItem(pt, 3); } // Grass
|
||||
if (type == 1) { dropItem(world, pt, 4); } // Stone
|
||||
else if (type == 2) { dropItem(world, pt, 3); } // Grass
|
||||
else if (type == 7) { } // Bedrock
|
||||
else if (type == 8) { } // Water
|
||||
else if (type == 9) { } // Water
|
||||
else if (type == 10) { } // Lava
|
||||
else if (type == 11) { } // Lava
|
||||
else if (type == 13) { // Gravel
|
||||
dropItem(pt, type);
|
||||
dropItem(world, pt, type);
|
||||
|
||||
if (random.nextDouble() >= 0.9) {
|
||||
dropItem(pt, 318);
|
||||
dropItem(world, pt, 318);
|
||||
}
|
||||
}
|
||||
else if (type == 16) { dropItem(pt, 263); } // Coal ore
|
||||
else if (type == 16) { dropItem(world, pt, 263); } // Coal ore
|
||||
else if (type == 18) { // Leaves
|
||||
if (random.nextDouble() > 0.95) {
|
||||
dropItem(pt, 6);
|
||||
dropItem(world, pt, 6);
|
||||
}
|
||||
}
|
||||
else if (type == 20) { } // Glass
|
||||
else if (type == 43) { dropItem(pt, 44); } // Double step
|
||||
else if (type == 43) { dropItem(world, pt, 44); } // Double step
|
||||
else if (type == 47) { } // Bookshelves
|
||||
else if (type == 51) { } // Fire
|
||||
else if (type == 52) { } // Mob spawner
|
||||
else if (type == 53) { dropItem(pt, 5); } // Wooden stairs
|
||||
else if (type == 55) { dropItem(pt, 331); } // Redstone wire
|
||||
else if (type == 56) { dropItem(pt, 264); } // Diamond ore
|
||||
else if (type == 59) { dropItem(pt, 295); } // Crops
|
||||
else if (type == 60) { dropItem(pt, 3); } // Soil
|
||||
else if (type == 62) { dropItem(pt, 61); } // Furnace
|
||||
else if (type == 63) { dropItem(pt, 323); } // Sign post
|
||||
else if (type == 64) { dropItem(pt, 324); } // Wood door
|
||||
else if (type == 67) { dropItem(pt, 4); } // Cobblestone stairs
|
||||
else if (type == 68) { dropItem(pt, 323); } // Wall sign
|
||||
else if (type == 71) { dropItem(pt, 330); } // Iron door
|
||||
else if (type == 73) { dropItem(pt, 331, 1, 4); } // Redstone ore
|
||||
else if (type == 74) { dropItem(pt, 331, 1, 4); } // Glowing redstone ore
|
||||
else if (type == 75) { dropItem(pt, 76); } // Redstone torch
|
||||
else if (type == 53) { dropItem(world, pt, 5); } // Wooden stairs
|
||||
else if (type == 55) { dropItem(world, pt, 331); } // Redstone wire
|
||||
else if (type == 56) { dropItem(world, pt, 264); } // Diamond ore
|
||||
else if (type == 59) { dropItem(world, pt, 295); } // Crops
|
||||
else if (type == 60) { dropItem(world, pt, 3); } // Soil
|
||||
else if (type == 62) { dropItem(world, pt, 61); } // Furnace
|
||||
else if (type == 63) { dropItem(world, pt, 323); } // Sign post
|
||||
else if (type == 64) { dropItem(world, pt, 324); } // Wood door
|
||||
else if (type == 67) { dropItem(world, pt, 4); } // Cobblestone stairs
|
||||
else if (type == 68) { dropItem(world, pt, 323); } // Wall sign
|
||||
else if (type == 71) { dropItem(world, pt, 330); } // Iron door
|
||||
else if (type == 73) { dropItem(world, pt, 331, 1, 4); } // Redstone ore
|
||||
else if (type == 74) { dropItem(world, pt, 331, 1, 4); } // Glowing redstone ore
|
||||
else if (type == 75) { dropItem(world, pt, 76); } // Redstone torch
|
||||
else if (type == 78) { } // Snow
|
||||
else if (type == 79) { } // Ice
|
||||
else if (type == 82) { dropItem(pt, 337, 1, 4); } // Clay
|
||||
else if (type == 83) { dropItem(pt, 338); } // Reed
|
||||
else if (type == 89) { dropItem(pt, 348); } // Lightstone
|
||||
else if (type == 82) { dropItem(world, pt, 337, 1, 4); } // Clay
|
||||
else if (type == 83) { dropItem(world, pt, 338); } // Reed
|
||||
else if (type == 89) { dropItem(world, pt, 348); } // Lightstone
|
||||
else if (type == 90) { } // Portal
|
||||
else if (type != 0) {
|
||||
dropItem(pt, type);
|
||||
dropItem(world, pt, type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@ public class HMServerInterface extends ServerInterface {
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
public int killMobs(Vector origin, int radius) {
|
||||
public int killMobs(LocalWorld world, Vector origin, int radius) {
|
||||
int killed = 0;
|
||||
|
||||
for (Mob mob : etc.getServer().getMobList()) {
|
||||
|
@ -17,53 +17,48 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.io.*;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.bags.BlockBag;
|
||||
import com.sk89q.worldedit.blocks.*;
|
||||
import com.sk89q.worldedit.data.*;
|
||||
import com.sk89q.worldedit.filters.*;
|
||||
import com.sk89q.worldedit.snapshots.*;
|
||||
import com.sk89q.worldedit.regions.*;
|
||||
import com.sk89q.worldedit.patterns.*;
|
||||
|
||||
/**
|
||||
* Plugin base.
|
||||
* The event listener for WorldEdit in hMod.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class HMWorldEditListener extends PluginListener {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
|
||||
|
||||
/**
|
||||
* WorldEditLibrary's properties file.
|
||||
*/
|
||||
private PropertiesFile properties;
|
||||
|
||||
/**
|
||||
* Main WorldEdit controller.
|
||||
*/
|
||||
private WorldEditController controller = new WorldEditController();
|
||||
private WorldEditController controller;
|
||||
/**
|
||||
* Configuration.
|
||||
*/
|
||||
private LocalConfiguration config;
|
||||
/**
|
||||
* A copy of the server instance. This is where all world<->WorldEdit calls
|
||||
* will go through.
|
||||
*/
|
||||
private ServerInterface server;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param server
|
||||
*/
|
||||
public HMWorldEditListener(ServerInterface server) {
|
||||
this.server = server;
|
||||
|
||||
config = new HMConfiguration();
|
||||
controller = new WorldEditController(server, config);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
@Override
|
||||
public void onDisconnect(Player player) {
|
||||
controller.handleDisconnect(new HMPlayer(player));
|
||||
controller.handleDisconnect(wrapPlayer(player));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +67,7 @@ public class HMWorldEditListener extends PluginListener {
|
||||
* @param player
|
||||
*/
|
||||
public void onArmSwing(Player player) {
|
||||
controller.handleArmSwing(new HMPlayer(player));
|
||||
controller.handleArmSwing(wrapPlayer(player));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +86,7 @@ public class HMWorldEditListener extends PluginListener {
|
||||
Vector pos = new Vector(blockClicked.getX(),
|
||||
blockClicked.getY(),
|
||||
blockClicked.getZ());
|
||||
return controller.handleBlockRightClick(new HMPlayer(player), pos);
|
||||
return controller.handleBlockRightClick(wrapPlayer(player), null, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +102,7 @@ public class HMWorldEditListener extends PluginListener {
|
||||
Vector pos = new Vector(blockClicked.getX(),
|
||||
blockClicked.getY(),
|
||||
blockClicked.getZ());
|
||||
return controller.handleBlockLeftClick(new HMPlayer(player), pos);
|
||||
return controller.handleBlockLeftClick(wrapPlayer(player), null, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,81 +113,21 @@ public class HMWorldEditListener extends PluginListener {
|
||||
*/
|
||||
@Override
|
||||
public boolean onCommand(Player player, String[] split) {
|
||||
return controller.handleCommand(new HMPlayer(player), split);
|
||||
return controller.handleCommand(wrapPlayer(player), split);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration.
|
||||
*/
|
||||
public void loadConfiguration() {
|
||||
if (properties == null) {
|
||||
properties = new PropertiesFile("worldedit.properties");
|
||||
} else {
|
||||
try {
|
||||
properties.load();
|
||||
} catch (IOException e) {
|
||||
logger.warning("worldedit.properties could not be loaded: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
controller.profile = properties.getBoolean("debug-profile", false);
|
||||
controller.wandItem = properties.getInt("wand-item", 271);
|
||||
controller.defaultChangeLimit = Math.max(-1, properties.getInt("default-max-blocks-changed", -1));
|
||||
controller.maxChangeLimit = Math.max(-1, properties.getInt("max-blocks-changed", -1));
|
||||
controller.maxRadius = Math.max(-1, properties.getInt("max-radius", -1));
|
||||
controller.maxSuperPickaxeSize = Math.max(1, properties.getInt("max-super-pickaxe-size", 5));
|
||||
controller.registerHelp = properties.getBoolean("register-help", true);
|
||||
controller.logComands = properties.getBoolean("log-commands", false);
|
||||
controller.superPickaxeDrop = properties.getBoolean("super-pickaxe-drop-items", true);
|
||||
controller.superPickaxeManyDrop = properties.getBoolean("super-pickaxe-many-drop-items", false);
|
||||
controller.noDoubleSlash = properties.getBoolean("no-double-slash", false);
|
||||
controller.useInventory = properties.getBoolean("use-inventory", false);
|
||||
controller.useInventoryOverride = properties.getBoolean("use-inventory-override", false);
|
||||
|
||||
// Get allowed blocks
|
||||
controller.allowedBlocks = new HashSet<Integer>();
|
||||
for (String b : properties.getString("allowed-blocks",
|
||||
WorldEditController.getDefaultAllowedBlocks()).split(",")) {
|
||||
try {
|
||||
controller.allowedBlocks.add(Integer.parseInt(b));
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String snapshotsDir = properties.getString("snapshots-dir", "");
|
||||
if (!snapshotsDir.trim().equals("")) {
|
||||
controller.snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
} else {
|
||||
controller.snapshotRepo = null;
|
||||
}
|
||||
|
||||
String type = properties.getString("shell-save-type", "").trim();
|
||||
controller.shellSaveType = type.equals("") ? null : type;
|
||||
|
||||
String logFile = properties.getString("log-file", "");
|
||||
if (!logFile.equals("")) {
|
||||
try {
|
||||
FileHandler handler = new FileHandler(logFile, true);
|
||||
handler.setFormatter(new LogFormat());
|
||||
logger.addHandler(handler);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not use log file " + logFile + ": "
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
for (Handler handler : logger.getHandlers()) {
|
||||
logger.removeHandler(handler);
|
||||
}
|
||||
}
|
||||
config.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register commands with help.
|
||||
*/
|
||||
public void registerCommands() {
|
||||
if (controller.registerHelp) {
|
||||
if (config.registerHelp) {
|
||||
for (Map.Entry<String,String> entry : controller.getCommands().entrySet()) {
|
||||
etc.getInstance().addCommand(entry.getKey(), entry.getValue());
|
||||
}
|
||||
@ -221,7 +156,17 @@ public class HMWorldEditListener extends PluginListener {
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public WorldEditSession _bridgeSession(Player player) {
|
||||
return controller.getBridgeSession(new HMPlayer(player));
|
||||
public LocalSession _bridgeSession(Player player) {
|
||||
return controller.getBridgeSession(wrapPlayer(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a hMod player for WorldEdit.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
private LocalPlayer wrapPlayer(Player player) {
|
||||
return new HMPlayer(server, player);
|
||||
}
|
||||
}
|
||||
|
@ -15,13 +15,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.worldedit.ServerInterface;
|
||||
|
||||
/**
|
||||
* Entry point for the plugin for hey0's mod.
|
||||
*
|
||||
@ -31,18 +29,29 @@ public class WorldEdit extends Plugin {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
|
||||
/**
|
||||
* WorldEditLibrary instance.
|
||||
*/
|
||||
private static final HMWorldEditListener listener = new HMWorldEditListener();
|
||||
private static final Logger logger = Logger
|
||||
.getLogger("Minecraft.WorldEdit");
|
||||
|
||||
/**
|
||||
* WorldEdit version, fetched from the .jar's manifest. Used to print the
|
||||
* WorldEdit version in various places.
|
||||
* The event listener for WorldEdit an hMod. Configuration and such is
|
||||
* also loaded here as well, although the core of the WorldEdit is
|
||||
* actually in com.sk89q.worldedit.WorldEditController and is merely
|
||||
* loaded by this listener.
|
||||
*/
|
||||
private final HMWorldEditListener listener;
|
||||
|
||||
/**
|
||||
* WorldEdit version, fetched from the .jar's manifest.
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* Construct an instance of the plugin.
|
||||
*/
|
||||
public WorldEdit() {
|
||||
listener = new HMWorldEditListener(new HMServerInterface());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the plugin.
|
||||
*/
|
||||
@ -63,8 +72,6 @@ public class WorldEdit extends Plugin {
|
||||
loader.addListener(PluginLoader.Hook.ARM_SWING, listener, this,
|
||||
PluginListener.Priority.MEDIUM);
|
||||
|
||||
ServerInterface.setup(new HMServerInterface());
|
||||
|
||||
logger.log(Level.INFO, "WorldEdit version " + getVersion() + " loaded");
|
||||
}
|
||||
|
||||
@ -114,13 +121,4 @@ public class WorldEdit extends Plugin {
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the listener.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HMWorldEditListener getListener() {
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
|
101
src/com/sk89q/util/StringUtil.java
Normale Datei
101
src/com/sk89q/util/StringUtil.java
Normale Datei
@ -0,0 +1,101 @@
|
||||
// $Id$
|
||||
/*
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.util;
|
||||
|
||||
/**
|
||||
* String utilities.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class StringUtil {
|
||||
/**
|
||||
* Trim a string if it is longer than a certain length.
|
||||
*
|
||||
* @param str
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
public static String trimLength(String str, int len) {
|
||||
if (str.length() > len) {
|
||||
return str.substring(0, len);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join an array of strings into a string.
|
||||
*
|
||||
* @param str
|
||||
* @param delimiter
|
||||
* @param initialIndex
|
||||
* @return
|
||||
*/
|
||||
public static String joinString(String[] str, String delimiter,
|
||||
int initialIndex) {
|
||||
if (str.length == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder(str[initialIndex]);
|
||||
for (int i = initialIndex + 1; i < str.length; i++) {
|
||||
buffer.append(delimiter).append(str[i]);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join an array of strings into a string.
|
||||
*
|
||||
* @param str
|
||||
* @param delimiter
|
||||
* @param initialIndex
|
||||
* @return
|
||||
*/
|
||||
public static String joinString(Object[] str, String delimiter,
|
||||
int initialIndex) {
|
||||
if (str.length == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder(str[initialIndex].toString());
|
||||
for (int i = initialIndex + 1; i < str.length; i++) {
|
||||
buffer.append(delimiter).append(str[i].toString());
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join an array of strings into a string.
|
||||
*
|
||||
* @param str
|
||||
* @param delimiter
|
||||
* @param initialIndex
|
||||
* @return
|
||||
*/
|
||||
public static String joinString(int[] str, String delimiter,
|
||||
int initialIndex) {
|
||||
if (str.length == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex]));
|
||||
for (int i = initialIndex + 1; i < str.length; i++) {
|
||||
buffer.append(delimiter).append(Integer.toString(str[i]));
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
101
src/com/sk89q/worldedit/BlockWorldVector.java
Normale Datei
101
src/com/sk89q/worldedit/BlockWorldVector.java
Normale Datei
@ -0,0 +1,101 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
/**
|
||||
* Extension of Vector that supports being compared as ints (for accuracy).
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class BlockWorldVector extends WorldVector {
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public BlockWorldVector(WorldVector pt) {
|
||||
super(pt.getWorld(), pt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public BlockWorldVector(LocalWorld world, Vector pt) {
|
||||
super(world, pt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public BlockWorldVector(LocalWorld world, int x, int y, int z) {
|
||||
super(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public BlockWorldVector(LocalWorld world, float x, float y, float z) {
|
||||
super(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public BlockWorldVector(LocalWorld world, double x, double y, double z) {
|
||||
super(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if another object is equivalent.
|
||||
*
|
||||
* @param obj
|
||||
* @return whether the other object is equivalent
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof WorldVector)) {
|
||||
return false;
|
||||
}
|
||||
WorldVector other = (WorldVector)obj;
|
||||
return (int)other.x == (int)this.x && (int)other.y == (int)this.y
|
||||
&& (int)other.z == (int)this.z;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash code.
|
||||
*
|
||||
* @return hash code
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (Integer.valueOf((int)x).hashCode() >> 13) ^
|
||||
(Integer.valueOf((int)y).hashCode() >> 7) ^
|
||||
Integer.valueOf((int)z).hashCode();
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
package com.sk89q.worldedit;
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
@ -18,7 +17,8 @@ package com.sk89q.worldedit;
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
import com.sk89q.worldedit.blocks.*;
|
||||
import com.sk89q.worldedit.data.*;
|
||||
import org.jnbt.*;
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
@ -29,7 +29,6 @@ import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.regions.*;
|
||||
import com.sk89q.worldedit.bags.*;
|
||||
import com.sk89q.worldedit.blocks.*;
|
||||
@ -37,11 +36,11 @@ import com.sk89q.worldedit.patterns.*;
|
||||
|
||||
/**
|
||||
* This class can wrap all block editing operations into one "edit session" that
|
||||
* stores the state of the blocks before modification. This allows for easy
|
||||
* undo or redo. In addition to that, this class can use a "queue mode" that
|
||||
* will know how to handle some special types of items such as signs and
|
||||
* torches. For example, torches must be placed only after there is already
|
||||
* a block below it, otherwise the torch will be placed as an item.
|
||||
* stores the state of the blocks before modification. This allows for easy undo
|
||||
* or redo. In addition to that, this class can use a "queue mode" that will
|
||||
* know how to handle some special types of items such as signs and torches. For
|
||||
* example, torches must be placed only after there is already a block below it,
|
||||
* otherwise the torch will be placed as an item.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
@ -55,31 +54,35 @@ public class EditSession {
|
||||
* Server interface.
|
||||
*/
|
||||
private ServerInterface server;
|
||||
/**
|
||||
* World.
|
||||
*/
|
||||
private LocalWorld world;
|
||||
|
||||
/**
|
||||
* Stores the original blocks before modification.
|
||||
*/
|
||||
private DoubleArrayList<BlockVector,BaseBlock> original =
|
||||
new DoubleArrayList<BlockVector,BaseBlock>(true);
|
||||
private DoubleArrayList<BlockVector, BaseBlock> original = new DoubleArrayList<BlockVector, BaseBlock>(
|
||||
true);
|
||||
/**
|
||||
* Stores the current blocks.
|
||||
*/
|
||||
private DoubleArrayList<BlockVector,BaseBlock> current =
|
||||
new DoubleArrayList<BlockVector,BaseBlock>(false);
|
||||
private DoubleArrayList<BlockVector, BaseBlock> current = new DoubleArrayList<BlockVector, BaseBlock>(
|
||||
false);
|
||||
/**
|
||||
* Blocks that should be placed before last.
|
||||
*/
|
||||
private DoubleArrayList<BlockVector,BaseBlock> queueAfter =
|
||||
new DoubleArrayList<BlockVector,BaseBlock>(false);
|
||||
private DoubleArrayList<BlockVector, BaseBlock> queueAfter = new DoubleArrayList<BlockVector, BaseBlock>(
|
||||
false);
|
||||
/**
|
||||
* Blocks that should be placed last.
|
||||
*/
|
||||
private DoubleArrayList<BlockVector,BaseBlock> queueLast =
|
||||
new DoubleArrayList<BlockVector,BaseBlock>(false);
|
||||
private DoubleArrayList<BlockVector, BaseBlock> queueLast = new DoubleArrayList<BlockVector, BaseBlock>(
|
||||
false);
|
||||
/**
|
||||
* The maximum number of blocks to change at a time. If this number is
|
||||
* exceeded, a MaxChangedBlocksException exception will be
|
||||
* raised. -1 indicates no limit.
|
||||
* exceeded, a MaxChangedBlocksException exception will be raised. -1
|
||||
* indicates no limit.
|
||||
*/
|
||||
private int maxBlocks = -1;
|
||||
/**
|
||||
@ -98,25 +101,38 @@ public class EditSession {
|
||||
|
||||
/**
|
||||
* Construct the object with a maximum number of blocks.
|
||||
*
|
||||
* @param server
|
||||
* @param world
|
||||
* @param maxBlocks
|
||||
*/
|
||||
public EditSession(int maxBlocks) {
|
||||
public EditSession(ServerInterface server, LocalWorld world, int maxBlocks) {
|
||||
if (maxBlocks < -1) {
|
||||
throw new IllegalArgumentException("Max blocks must be >= -1");
|
||||
}
|
||||
|
||||
this.maxBlocks = maxBlocks;
|
||||
server = ServerInterface.getInstance();
|
||||
this.server = server;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the object with a maximum number of blocks and a block bag.
|
||||
*
|
||||
* @param server
|
||||
* @param maxBlocks
|
||||
* @blockBag
|
||||
*/
|
||||
public EditSession(int maxBlocks, BlockBag blockBag) {
|
||||
public EditSession(ServerInterface server, LocalWorld world, int maxBlocks,
|
||||
BlockBag blockBag) {
|
||||
if (maxBlocks < -1) {
|
||||
throw new IllegalArgumentException("Max blocks must be >= -1");
|
||||
}
|
||||
|
||||
this.maxBlocks = maxBlocks;
|
||||
this.blockBag = blockBag;
|
||||
server = ServerInterface.getInstance();
|
||||
this.server = server;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,14 +149,14 @@ public class EditSession {
|
||||
}
|
||||
|
||||
// Clear the chest so that it doesn't drop items
|
||||
if (server.getBlockType(pt) == 54 && blockBag == null) {
|
||||
server.clearChest(pt);
|
||||
if (server.getBlockType(world, pt) == 54 && blockBag == null) {
|
||||
server.clearChest(world, pt);
|
||||
}
|
||||
|
||||
int id = block.getID();
|
||||
|
||||
if (blockBag != null) {
|
||||
int existing = server.getBlockType(pt);
|
||||
int existing = server.getBlockType(world, pt);
|
||||
|
||||
if (id > 0) {
|
||||
try {
|
||||
@ -161,25 +177,25 @@ public class EditSession {
|
||||
}
|
||||
}
|
||||
|
||||
boolean result = server.setBlockType(pt, id);
|
||||
boolean result = server.setBlockType(world, pt, id);
|
||||
if (id != 0) {
|
||||
if (BlockType.usesData(id)) {
|
||||
server.setBlockData(pt, block.getData());
|
||||
server.setBlockData(world, pt, block.getData());
|
||||
}
|
||||
|
||||
// Signs
|
||||
if (block instanceof SignBlock) {
|
||||
SignBlock signBlock = (SignBlock)block;
|
||||
SignBlock signBlock = (SignBlock) block;
|
||||
String[] text = signBlock.getText();
|
||||
server.setSignText(pt, text);
|
||||
// Chests
|
||||
server.setSignText(world, pt, text);
|
||||
// Chests
|
||||
} else if (block instanceof ChestBlock && blockBag == null) {
|
||||
ChestBlock chestBlock = (ChestBlock)block;
|
||||
server.setChestContents(pt, chestBlock.getItems());
|
||||
// Mob spawners
|
||||
ChestBlock chestBlock = (ChestBlock) block;
|
||||
server.setChestContents(world, pt, chestBlock.getItems());
|
||||
// Mob spawners
|
||||
} else if (block instanceof MobSpawnerBlock) {
|
||||
MobSpawnerBlock mobSpawnerblock = (MobSpawnerBlock)block;
|
||||
server.setMobSpawnerType(pt, mobSpawnerblock.getMobType());
|
||||
MobSpawnerBlock mobSpawnerblock = (MobSpawnerBlock) block;
|
||||
server.setMobSpawnerType(world, pt, mobSpawnerblock.getMobType());
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,24 +204,24 @@ public class EditSession {
|
||||
|
||||
/**
|
||||
* Sets the block at position x, y, z with a block type. If queue mode is
|
||||
* enabled, blocks may not be actually set in world until flushQueue()
|
||||
* is called.
|
||||
* enabled, blocks may not be actually set in world until flushQueue() is
|
||||
* called.
|
||||
*
|
||||
* @param pt
|
||||
* @param block
|
||||
* @return Whether the block changed -- not entirely dependable
|
||||
*/
|
||||
public boolean setBlock(Vector pt, BaseBlock block)
|
||||
throws MaxChangedBlocksException {
|
||||
throws MaxChangedBlocksException {
|
||||
BlockVector blockPt = pt.toBlockVector();
|
||||
|
||||
//if (!original.containsKey(blockPt)) {
|
||||
original.put(blockPt, getBlock(pt));
|
||||
// if (!original.containsKey(blockPt)) {
|
||||
original.put(blockPt, getBlock(pt));
|
||||
|
||||
if (maxBlocks != -1 && original.size() > maxBlocks) {
|
||||
throw new MaxChangedBlocksException(maxBlocks);
|
||||
}
|
||||
//}
|
||||
if (maxBlocks != -1 && original.size() > maxBlocks) {
|
||||
throw new MaxChangedBlocksException(maxBlocks);
|
||||
}
|
||||
// }
|
||||
|
||||
current.put(pt.toBlockVector(), block);
|
||||
|
||||
@ -242,7 +258,7 @@ public class EditSession {
|
||||
if (BlockType.shouldPlaceLast(block.getID())) {
|
||||
queueLast.put(pt.toBlockVector(), block);
|
||||
return getBlock(pt).getID() != block.getID();
|
||||
// Destroy torches, etc. first
|
||||
// Destroy torches, etc. first
|
||||
} else if (BlockType.shouldPlaceLast(getBlock(pt).getID())) {
|
||||
rawSetBlock(pt, new BaseBlock(0));
|
||||
} else {
|
||||
@ -264,11 +280,12 @@ public class EditSession {
|
||||
// In the case of the queue, the block may have not actually been
|
||||
// changed yet
|
||||
if (queued) {
|
||||
/*BlockVector blockPt = pt.toBlockVector();
|
||||
|
||||
if (current.containsKey(blockPt)) {
|
||||
return current.get(blockPt);
|
||||
}*/
|
||||
/*
|
||||
* BlockVector blockPt = pt.toBlockVector();
|
||||
*
|
||||
* if (current.containsKey(blockPt)) { return current.get(blockPt);
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
return rawGetBlock(pt);
|
||||
@ -281,21 +298,21 @@ public class EditSession {
|
||||
* @return BaseBlock
|
||||
*/
|
||||
public BaseBlock rawGetBlock(Vector pt) {
|
||||
int type = server.getBlockType(pt);
|
||||
int data = server.getBlockData(pt);
|
||||
int type = server.getBlockType(world, pt);
|
||||
int data = server.getBlockData(world, pt);
|
||||
|
||||
// Sign
|
||||
if (type == 63 || type == 68) {
|
||||
String[] text = server.getSignText(pt);
|
||||
String[] text = server.getSignText(world, pt);
|
||||
return new SignBlock(type, data, text);
|
||||
// Chest
|
||||
// Chest
|
||||
} else if (type == 54) {
|
||||
BaseItemStack[] items =
|
||||
server.getChestContents(pt);
|
||||
BaseItemStack[] items = server.getChestContents(world, pt);
|
||||
return new ChestBlock(data, items);
|
||||
// Mob spawner
|
||||
// Mob spawner
|
||||
} else if (type == 52) {
|
||||
return new MobSpawnerBlock(data, server.getMobSpawnerType(pt));
|
||||
return new MobSpawnerBlock(data,
|
||||
server.getMobSpawnerType(world, pt));
|
||||
} else {
|
||||
return new BaseBlock(type, data);
|
||||
}
|
||||
@ -305,9 +322,9 @@ public class EditSession {
|
||||
* Restores all blocks to their initial state.
|
||||
*/
|
||||
public void undo() {
|
||||
for (Map.Entry<BlockVector,BaseBlock> entry : original) {
|
||||
BlockVector pt = (BlockVector)entry.getKey();
|
||||
smartSetBlock(pt, (BaseBlock)entry.getValue());
|
||||
for (Map.Entry<BlockVector, BaseBlock> entry : original) {
|
||||
BlockVector pt = (BlockVector) entry.getKey();
|
||||
smartSetBlock(pt, (BaseBlock) entry.getValue());
|
||||
}
|
||||
flushQueue();
|
||||
}
|
||||
@ -316,9 +333,9 @@ public class EditSession {
|
||||
* Sets to new state.
|
||||
*/
|
||||
public void redo() {
|
||||
for (Map.Entry<BlockVector,BaseBlock> entry : current) {
|
||||
BlockVector pt = (BlockVector)entry.getKey();
|
||||
smartSetBlock(pt, (BaseBlock)entry.getValue());
|
||||
for (Map.Entry<BlockVector, BaseBlock> entry : current) {
|
||||
BlockVector pt = (BlockVector) entry.getKey();
|
||||
smartSetBlock(pt, (BaseBlock) entry.getValue());
|
||||
}
|
||||
flushQueue();
|
||||
}
|
||||
@ -332,8 +349,8 @@ public class EditSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum number of blocks that can be changed. -1 will be
|
||||
* returned if disabled.
|
||||
* Get the maximum number of blocks that can be changed. -1 will be returned
|
||||
* if disabled.
|
||||
*
|
||||
* @return block change limit
|
||||
*/
|
||||
@ -344,7 +361,8 @@ public class EditSession {
|
||||
/**
|
||||
* Set the maximum number of blocks that can be changed.
|
||||
*
|
||||
* @param maxBlocks -1 to disable
|
||||
* @param maxBlocks
|
||||
* -1 to disable
|
||||
*/
|
||||
public void setBlockChangeLimit(int maxBlocks) {
|
||||
if (maxBlocks < -1) {
|
||||
@ -383,19 +401,21 @@ public class EditSession {
|
||||
* Finish off the queue.
|
||||
*/
|
||||
public void flushQueue() {
|
||||
if (!queued) { return; }
|
||||
if (!queued) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<BlockVector,BaseBlock> entry : queueAfter) {
|
||||
BlockVector pt = (BlockVector)entry.getKey();
|
||||
rawSetBlock(pt, (BaseBlock)entry.getValue());
|
||||
for (Map.Entry<BlockVector, BaseBlock> entry : queueAfter) {
|
||||
BlockVector pt = (BlockVector) entry.getKey();
|
||||
rawSetBlock(pt, (BaseBlock) entry.getValue());
|
||||
}
|
||||
|
||||
// We don't want to place these blocks if other blocks were missing
|
||||
// because it might cause the items to drop
|
||||
if (blockBag == null || missingBlocks.size() == 0) {
|
||||
for (Map.Entry<BlockVector,BaseBlock> entry : queueLast) {
|
||||
BlockVector pt = (BlockVector)entry.getKey();
|
||||
rawSetBlock(pt, (BaseBlock)entry.getValue());
|
||||
for (Map.Entry<BlockVector, BaseBlock> entry : queueLast) {
|
||||
BlockVector pt = (BlockVector) entry.getKey();
|
||||
rawSetBlock(pt, (BaseBlock) entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,9 +433,8 @@ public class EditSession {
|
||||
* @param recursive
|
||||
* @return number of blocks affected
|
||||
*/
|
||||
public int fillXZ(Vector origin, BaseBlock block,
|
||||
int radius, int depth, boolean recursive)
|
||||
throws MaxChangedBlocksException {
|
||||
public int fillXZ(Vector origin, BaseBlock block, int radius, int depth,
|
||||
boolean recursive) throws MaxChangedBlocksException {
|
||||
|
||||
int affected = 0;
|
||||
int originX = origin.getBlockX();
|
||||
@ -491,7 +510,7 @@ public class EditSession {
|
||||
* @return
|
||||
*/
|
||||
private int fillY(int x, int cy, int z, BaseBlock block, int minY)
|
||||
throws MaxChangedBlocksException {
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int y = cy; y >= minY; y--) {
|
||||
@ -518,9 +537,8 @@ public class EditSession {
|
||||
* @param recursive
|
||||
* @return number of blocks affected
|
||||
*/
|
||||
public int fillXZ(Vector origin, Pattern pattern,
|
||||
int radius, int depth, boolean recursive)
|
||||
throws MaxChangedBlocksException {
|
||||
public int fillXZ(Vector origin, Pattern pattern, int radius, int depth,
|
||||
boolean recursive) throws MaxChangedBlocksException {
|
||||
|
||||
int affected = 0;
|
||||
int originX = origin.getBlockX();
|
||||
@ -596,7 +614,7 @@ public class EditSession {
|
||||
* @return
|
||||
*/
|
||||
private int fillY(int x, int cy, int z, Pattern pattern, int minY)
|
||||
throws MaxChangedBlocksException {
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int y = cy; y >= minY; y--) {
|
||||
@ -621,8 +639,8 @@ public class EditSession {
|
||||
* @param height
|
||||
* @return number of blocks affected
|
||||
*/
|
||||
public int removeAbove(Vector pos, int size, int height) throws
|
||||
MaxChangedBlocksException {
|
||||
public int removeAbove(Vector pos, int size, int height)
|
||||
throws MaxChangedBlocksException {
|
||||
int maxY = Math.min(127, pos.getBlockY() + height - 1);
|
||||
size--;
|
||||
int affected = 0;
|
||||
@ -655,8 +673,8 @@ public class EditSession {
|
||||
* @param height
|
||||
* @return number of blocks affected
|
||||
*/
|
||||
public int removeBelow(Vector pos, int size, int height) throws
|
||||
MaxChangedBlocksException {
|
||||
public int removeBelow(Vector pos, int size, int height)
|
||||
throws MaxChangedBlocksException {
|
||||
int minY = Math.max(0, pos.getBlockY() - height);
|
||||
size--;
|
||||
int affected = 0;
|
||||
@ -689,8 +707,8 @@ public class EditSession {
|
||||
* @param size
|
||||
* @return number of blocks affected
|
||||
*/
|
||||
public int removeNear(Vector pos, int blockType, int size) throws
|
||||
MaxChangedBlocksException {
|
||||
public int removeNear(Vector pos, int blockType, int size)
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
BaseBlock air = new BaseBlock(0);
|
||||
|
||||
@ -807,13 +825,14 @@ public class EditSession {
|
||||
* Replaces all the blocks of a type inside a region to another block type.
|
||||
*
|
||||
* @param region
|
||||
* @param fromBlockType -1 for non-air
|
||||
* @param fromBlockType
|
||||
* -1 for non-air
|
||||
* @param toBlockType
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int replaceBlocks(Region region, Set<Integer> fromBlockTypes, BaseBlock toBlock)
|
||||
throws MaxChangedBlocksException {
|
||||
public int replaceBlocks(Region region, Set<Integer> fromBlockTypes,
|
||||
BaseBlock toBlock) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
if (region instanceof CuboidRegion) {
|
||||
@ -834,9 +853,9 @@ public class EditSession {
|
||||
Vector pt = new Vector(x, y, z);
|
||||
int curBlockType = getBlock(pt).getID();
|
||||
|
||||
if ((fromBlockTypes == null && curBlockType != 0) ||
|
||||
(fromBlockTypes != null &&
|
||||
fromBlockTypes.contains(curBlockType))) {
|
||||
if ((fromBlockTypes == null && curBlockType != 0)
|
||||
|| (fromBlockTypes != null && fromBlockTypes
|
||||
.contains(curBlockType))) {
|
||||
if (setBlock(pt, toBlock)) {
|
||||
affected++;
|
||||
}
|
||||
@ -848,8 +867,8 @@ public class EditSession {
|
||||
for (Vector pt : region) {
|
||||
int curBlockType = getBlock(pt).getID();
|
||||
|
||||
if (fromBlockTypes == null && curBlockType != 0 ||
|
||||
fromBlockTypes.contains(curBlockType)) {
|
||||
if (fromBlockTypes == null && curBlockType != 0
|
||||
|| fromBlockTypes.contains(curBlockType)) {
|
||||
if (setBlock(pt, toBlock)) {
|
||||
affected++;
|
||||
}
|
||||
@ -864,14 +883,14 @@ public class EditSession {
|
||||
* Replaces all the blocks of a type inside a region to another block type.
|
||||
*
|
||||
* @param region
|
||||
* @param fromBlockType -1 for non-air
|
||||
* @param fromBlockType
|
||||
* -1 for non-air
|
||||
* @param pattern
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int replaceBlocks(Region region, Set<Integer> fromBlockTypes,
|
||||
Pattern pattern)
|
||||
throws MaxChangedBlocksException {
|
||||
Pattern pattern) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
if (region instanceof CuboidRegion) {
|
||||
@ -892,9 +911,9 @@ public class EditSession {
|
||||
Vector pt = new Vector(x, y, z);
|
||||
int curBlockType = getBlock(pt).getID();
|
||||
|
||||
if ((fromBlockTypes == null && curBlockType != 0) ||
|
||||
(fromBlockTypes != null &&
|
||||
fromBlockTypes.contains(curBlockType))) {
|
||||
if ((fromBlockTypes == null && curBlockType != 0)
|
||||
|| (fromBlockTypes != null && fromBlockTypes
|
||||
.contains(curBlockType))) {
|
||||
if (setBlock(pt, pattern.next(pt))) {
|
||||
affected++;
|
||||
}
|
||||
@ -906,8 +925,8 @@ public class EditSession {
|
||||
for (Vector pt : region) {
|
||||
int curBlockType = getBlock(pt).getID();
|
||||
|
||||
if (fromBlockTypes == null && curBlockType != 0 ||
|
||||
fromBlockTypes.contains(curBlockType)) {
|
||||
if (fromBlockTypes == null && curBlockType != 0
|
||||
|| fromBlockTypes.contains(curBlockType)) {
|
||||
if (setBlock(pt, pattern.next(pt))) {
|
||||
affected++;
|
||||
}
|
||||
@ -942,23 +961,35 @@ public class EditSession {
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
if (setBlock(new Vector(x, y, minZ), block)) { affected++; }
|
||||
if (setBlock(new Vector(x, y, maxZ), block)) { affected++; }
|
||||
if (setBlock(new Vector(x, y, minZ), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(new Vector(x, y, maxZ), block)) {
|
||||
affected++;
|
||||
}
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
if (setBlock(new Vector(minX, y, z), block)) { affected++; }
|
||||
if (setBlock(new Vector(maxX, y, z), block)) { affected++; }
|
||||
if (setBlock(new Vector(minX, y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(new Vector(maxX, y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
if (setBlock(new Vector(x, minY, z), block)) { affected++; }
|
||||
if (setBlock(new Vector(x, maxY, z), block)) { affected++; }
|
||||
if (setBlock(new Vector(x, minY, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(new Vector(x, maxY, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -989,16 +1020,24 @@ public class EditSession {
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
if (setBlock(new Vector(x, y, minZ), block)) { affected++; }
|
||||
if (setBlock(new Vector(x, y, maxZ), block)) { affected++; }
|
||||
if (setBlock(new Vector(x, y, minZ), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(new Vector(x, y, maxZ), block)) {
|
||||
affected++;
|
||||
}
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
if (setBlock(new Vector(minX, y, z), block)) { affected++; }
|
||||
if (setBlock(new Vector(maxX, y, z), block)) { affected++; }
|
||||
if (setBlock(new Vector(minX, y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(new Vector(maxX, y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1019,7 +1058,7 @@ public class EditSession {
|
||||
Vector max = region.getMaximumPoint();
|
||||
|
||||
int upperY = Math.min(127, max.getBlockY() + 1);
|
||||
int lowerY = Math.max(0, min.getBlockY()- 1);
|
||||
int lowerY = Math.max(0, min.getBlockY() - 1);
|
||||
|
||||
int affected = 0;
|
||||
|
||||
@ -1057,9 +1096,8 @@ public class EditSession {
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int stackCuboidRegion(Region region, Vector dir,
|
||||
int count, boolean copyAir)
|
||||
throws MaxChangedBlocksException {
|
||||
public int stackCuboidRegion(Region region, Vector dir, int count,
|
||||
boolean copyAir) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
Vector min = region.getMinimumPoint();
|
||||
@ -1083,10 +1121,9 @@ public class EditSession {
|
||||
|
||||
if (!block.isAir() || copyAir) {
|
||||
for (int i = 1; i <= count; i++) {
|
||||
Vector pos = new Vector(
|
||||
x + xs * dir.getBlockX() * i,
|
||||
y + ys * dir.getBlockY() * i,
|
||||
z + zs * dir.getBlockZ() * i);
|
||||
Vector pos = new Vector(x + xs * dir.getBlockX()
|
||||
* i, y + ys * dir.getBlockY() * i, z + zs
|
||||
* dir.getBlockZ() * i);
|
||||
|
||||
if (setBlock(pos, block)) {
|
||||
affected++;
|
||||
@ -1111,8 +1148,8 @@ public class EditSession {
|
||||
* @return number of blocks moved
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int moveCuboidRegion(Region region, Vector dir,
|
||||
int distance, boolean copyAir, BaseBlock replace)
|
||||
public int moveCuboidRegion(Region region, Vector dir, int distance,
|
||||
boolean copyAir, BaseBlock replace)
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
@ -1130,7 +1167,7 @@ public class EditSession {
|
||||
Vector newMin = min.add(shift);
|
||||
Vector newMax = min.add(shift);
|
||||
|
||||
Map<Vector,BaseBlock> delayed = new LinkedHashMap<Vector,BaseBlock>();
|
||||
Map<Vector, BaseBlock> delayed = new LinkedHashMap<Vector, BaseBlock>();
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
@ -1146,8 +1183,10 @@ public class EditSession {
|
||||
// Don't want to replace the old block if it's in
|
||||
// the new area
|
||||
if (x >= newMin.getBlockX() && x <= newMax.getBlockX()
|
||||
&& y >= newMin.getBlockY() && y <= newMax.getBlockY()
|
||||
&& z >= newMin.getBlockZ() && z <= newMax.getBlockZ()) {
|
||||
&& y >= newMin.getBlockY()
|
||||
&& y <= newMax.getBlockY()
|
||||
&& z >= newMin.getBlockZ()
|
||||
&& z <= newMax.getBlockZ()) {
|
||||
} else {
|
||||
setBlock(pos, replace);
|
||||
}
|
||||
@ -1156,7 +1195,7 @@ public class EditSession {
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<Vector,BaseBlock> entry : delayed.entrySet()) {
|
||||
for (Map.Entry<Vector, BaseBlock> entry : delayed.entrySet()) {
|
||||
setBlock(entry.getKey(), entry.getValue());
|
||||
affected++;
|
||||
}
|
||||
@ -1172,7 +1211,8 @@ public class EditSession {
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int drainArea(Vector pos, int radius) throws MaxChangedBlocksException {
|
||||
public int drainArea(Vector pos, int radius)
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
HashSet<BlockVector> visited = new HashSet<BlockVector>();
|
||||
@ -1303,8 +1343,8 @@ public class EditSession {
|
||||
* @param block
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
private int makeHCylinderPoints(Vector center, int x, int z,
|
||||
int height, BaseBlock block) throws MaxChangedBlocksException {
|
||||
private int makeHCylinderPoints(Vector center, int x, int z, int height,
|
||||
BaseBlock block) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
if (x == 0) {
|
||||
@ -1350,8 +1390,8 @@ public class EditSession {
|
||||
* @return number of blocks set
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int makeHollowCylinder(Vector pos, BaseBlock block,
|
||||
int radius, int height) throws MaxChangedBlocksException {
|
||||
public int makeHollowCylinder(Vector pos, BaseBlock block, int radius,
|
||||
int height) throws MaxChangedBlocksException {
|
||||
int x = 0;
|
||||
int z = radius;
|
||||
int d = (5 - radius * 4) / 4;
|
||||
@ -1398,8 +1438,8 @@ public class EditSession {
|
||||
* @param block
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
private int makeCylinderPoints(Vector center, int x, int z,
|
||||
int height, BaseBlock block) throws MaxChangedBlocksException {
|
||||
private int makeCylinderPoints(Vector center, int x, int z, int height,
|
||||
BaseBlock block) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
if (x == z) {
|
||||
@ -1437,8 +1477,8 @@ public class EditSession {
|
||||
* @return number of blocks set
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int makeCylinder(Vector pos, BaseBlock block,
|
||||
int radius, int height) throws MaxChangedBlocksException {
|
||||
public int makeCylinder(Vector pos, BaseBlock block, int radius, int height)
|
||||
throws MaxChangedBlocksException {
|
||||
int x = 0;
|
||||
int z = radius;
|
||||
int d = (5 - radius * 4) / 4;
|
||||
@ -1485,8 +1525,8 @@ public class EditSession {
|
||||
* @return number of blocks changed
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int makeSphere(Vector pos, BaseBlock block, int radius, boolean filled)
|
||||
throws MaxChangedBlocksException {
|
||||
public int makeSphere(Vector pos, BaseBlock block, int radius,
|
||||
boolean filled) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int x = 0; x <= radius; x++) {
|
||||
@ -1496,14 +1536,30 @@ public class EditSession {
|
||||
double d = vec.distance(pos);
|
||||
|
||||
if (d <= radius + 0.5 && (filled || d >= radius - 0.5)) {
|
||||
if (setBlock(vec, block)) { affected++; }
|
||||
if (setBlock(pos.add(-x, y, z), block)) { affected++; }
|
||||
if (setBlock(pos.add(x, -y, z), block)) { affected++; }
|
||||
if (setBlock(pos.add(x, y, -z), block)) { affected++; }
|
||||
if (setBlock(pos.add(-x, -y, z), block)) { affected++; }
|
||||
if (setBlock(pos.add(x, -y, -z), block)) { affected++; }
|
||||
if (setBlock(pos.add(-x, y, -z), block)) { affected++; }
|
||||
if (setBlock(pos.add(-x, -y, -z), block)) { affected++; }
|
||||
if (setBlock(vec, block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(-x, y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(x, -y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(x, y, -z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(-x, -y, z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(x, -y, -z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(-x, y, -z), block)) {
|
||||
affected++;
|
||||
}
|
||||
if (setBlock(pos.add(-x, -y, -z), block)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1555,8 +1611,8 @@ public class EditSession {
|
||||
|| id == 53 // Wood steps
|
||||
|| id == 55 // Redstone wire
|
||||
|| id == 59 // Crops
|
||||
|| (id >= 63 && id <= 72)
|
||||
|| id == 75 // Redstone torch
|
||||
|| (id >= 63 && id <= 72) || id == 75 // Redstone
|
||||
// torch
|
||||
|| id == 76 // Redstone torch
|
||||
|| id == 77 // Stone button
|
||||
|| id == 78 // Snow
|
||||
@ -1599,7 +1655,8 @@ public class EditSession {
|
||||
*
|
||||
* @param pos
|
||||
* @param block
|
||||
* @param c 0-1 chance
|
||||
* @param c
|
||||
* 0-1 chance
|
||||
* @return whether a block was changed
|
||||
*/
|
||||
private boolean setChanceBlockIfAir(Vector pos, BaseBlock block, double c)
|
||||
@ -1617,10 +1674,10 @@ public class EditSession {
|
||||
*/
|
||||
private void makePumpkinPatch(Vector basePos)
|
||||
throws MaxChangedBlocksException {
|
||||
//BaseBlock logBlock = new BaseBlock(17);
|
||||
// BaseBlock logBlock = new BaseBlock(17);
|
||||
BaseBlock leavesBlock = new BaseBlock(18);
|
||||
|
||||
//setBlock(basePos.subtract(0, 1, 0), logBlock);
|
||||
// setBlock(basePos.subtract(0, 1, 0), logBlock);
|
||||
setBlockIfAir(basePos, leavesBlock);
|
||||
|
||||
makePumpkinPatchVine(basePos, basePos.add(0, 0, 1));
|
||||
@ -1637,8 +1694,10 @@ public class EditSession {
|
||||
*/
|
||||
private void makePumpkinPatchVine(Vector basePos, Vector pos)
|
||||
throws MaxChangedBlocksException {
|
||||
if (pos.distance(basePos) > 4) return;
|
||||
if (getBlock(pos).getID() != 0) return;
|
||||
if (pos.distance(basePos) > 4)
|
||||
return;
|
||||
if (getBlock(pos).getID() != 0)
|
||||
return;
|
||||
|
||||
for (int i = -1; i > -3; i--) {
|
||||
Vector testPos = pos.add(0, i, 0);
|
||||
@ -1655,20 +1714,28 @@ public class EditSession {
|
||||
int h = prng.nextInt(3) - 1;
|
||||
|
||||
if (t == 0) {
|
||||
if (prng.nextBoolean()) makePumpkinPatchVine(basePos, pos.add(1, 0, 0));
|
||||
if (prng.nextBoolean()) setBlockIfAir(pos.add(1, h, -1), new BaseBlock(18));
|
||||
if (prng.nextBoolean())
|
||||
makePumpkinPatchVine(basePos, pos.add(1, 0, 0));
|
||||
if (prng.nextBoolean())
|
||||
setBlockIfAir(pos.add(1, h, -1), new BaseBlock(18));
|
||||
setBlockIfAir(pos.add(0, 0, -1), new BaseBlock(86));
|
||||
} else if (t == 1) {
|
||||
if (prng.nextBoolean()) makePumpkinPatchVine(basePos, pos.add(0, 0, 1));
|
||||
if (prng.nextBoolean()) setBlockIfAir(pos.add(1, h, 0), new BaseBlock(18));
|
||||
if (prng.nextBoolean())
|
||||
makePumpkinPatchVine(basePos, pos.add(0, 0, 1));
|
||||
if (prng.nextBoolean())
|
||||
setBlockIfAir(pos.add(1, h, 0), new BaseBlock(18));
|
||||
setBlockIfAir(pos.add(1, 0, 1), new BaseBlock(86));
|
||||
} else if (t == 2) {
|
||||
if (prng.nextBoolean()) makePumpkinPatchVine(basePos, pos.add(0, 0, -1));
|
||||
if (prng.nextBoolean()) setBlockIfAir(pos.add(-1, h, 0), new BaseBlock(18));
|
||||
if (prng.nextBoolean())
|
||||
makePumpkinPatchVine(basePos, pos.add(0, 0, -1));
|
||||
if (prng.nextBoolean())
|
||||
setBlockIfAir(pos.add(-1, h, 0), new BaseBlock(18));
|
||||
setBlockIfAir(pos.add(-1, 0, 1), new BaseBlock(86));
|
||||
} else if (t == 3) {
|
||||
if (prng.nextBoolean()) makePumpkinPatchVine(basePos, pos.add(-1, 0, 0));
|
||||
if (prng.nextBoolean()) setBlockIfAir(pos.add(-1, h, -1), new BaseBlock(18));
|
||||
if (prng.nextBoolean())
|
||||
makePumpkinPatchVine(basePos, pos.add(-1, 0, 0));
|
||||
if (prng.nextBoolean())
|
||||
setBlockIfAir(pos.add(-1, h, -1), new BaseBlock(18));
|
||||
setBlockIfAir(pos.add(-1, 0, -1), new BaseBlock(86));
|
||||
}
|
||||
}
|
||||
@ -1684,13 +1751,17 @@ public class EditSession {
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int x = basePos.getBlockX() - size; x <= basePos.getBlockX() + size; x++) {
|
||||
for (int z = basePos.getBlockZ() - size; z <= basePos.getBlockZ() + size; z++) {
|
||||
for (int x = basePos.getBlockX() - size; x <= basePos.getBlockX()
|
||||
+ size; x++) {
|
||||
for (int z = basePos.getBlockZ() - size; z <= basePos.getBlockZ()
|
||||
+ size; z++) {
|
||||
// Don't want to be in the ground
|
||||
if (!getBlock(new Vector(x, basePos.getBlockY(), z)).isAir())
|
||||
continue;
|
||||
// The gods don't want a pumpkin patch here
|
||||
if (Math.random() < 0.98) { continue; }
|
||||
if (Math.random() < 0.98) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int y = basePos.getBlockY(); y >= basePos.getBlockY() - 10; y--) {
|
||||
// Check if we hit the ground
|
||||
@ -1722,13 +1793,17 @@ public class EditSession {
|
||||
boolean pineTree) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int x = basePos.getBlockX() - size; x <= basePos.getBlockX() + size; x++) {
|
||||
for (int z = basePos.getBlockZ() - size; z <= basePos.getBlockZ() + size; z++) {
|
||||
for (int x = basePos.getBlockX() - size; x <= basePos.getBlockX()
|
||||
+ size; x++) {
|
||||
for (int z = basePos.getBlockZ() - size; z <= basePos.getBlockZ()
|
||||
+ size; z++) {
|
||||
// Don't want to be in the ground
|
||||
if (!getBlock(new Vector(x, basePos.getBlockY(), z)).isAir())
|
||||
continue;
|
||||
// The gods don't want a tree here
|
||||
if (Math.random() >= density) { continue; } // def 0.05
|
||||
if (Math.random() >= density) {
|
||||
continue;
|
||||
} // def 0.05
|
||||
|
||||
for (int y = basePos.getBlockY(); y >= basePos.getBlockY() - 10; y--) {
|
||||
// Check if we hit the ground
|
||||
@ -1737,7 +1812,8 @@ public class EditSession {
|
||||
if (pineTree) {
|
||||
makePineTree(new Vector(x, y + 1, z));
|
||||
} else {
|
||||
server.generateTree(this, new Vector(x, y + 1, z));
|
||||
server.generateTree(this, world,
|
||||
new Vector(x, y + 1, z));
|
||||
}
|
||||
affected++;
|
||||
break;
|
||||
@ -1756,10 +1832,9 @@ public class EditSession {
|
||||
*
|
||||
* @param basePos
|
||||
*/
|
||||
private void makePineTree(Vector basePos)
|
||||
throws MaxChangedBlocksException {
|
||||
int trunkHeight = (int)Math.floor(Math.random() * 2) + 3;
|
||||
int height = (int)Math.floor(Math.random() * 5) + 8;
|
||||
private void makePineTree(Vector basePos) throws MaxChangedBlocksException {
|
||||
int trunkHeight = (int) Math.floor(Math.random() * 2) + 3;
|
||||
int height = (int) Math.floor(Math.random() * 5) + 8;
|
||||
|
||||
BaseBlock logBlock = new BaseBlock(17);
|
||||
BaseBlock leavesBlock = new BaseBlock(18);
|
||||
@ -1861,10 +1936,8 @@ public class EditSession {
|
||||
* @return
|
||||
*/
|
||||
public List<Countable<Integer>> getBlockDistribution(Region region) {
|
||||
List<Countable<Integer>> distribution
|
||||
= new ArrayList<Countable<Integer>>();
|
||||
Map<Integer,Countable<Integer>> map =
|
||||
new HashMap<Integer,Countable<Integer>>();
|
||||
List<Countable<Integer>> distribution = new ArrayList<Countable<Integer>>();
|
||||
Map<Integer, Countable<Integer>> map = new HashMap<Integer, Countable<Integer>>();
|
||||
|
||||
if (region instanceof CuboidRegion) {
|
||||
// Doing this for speed
|
||||
@ -1909,7 +1982,7 @@ public class EditSession {
|
||||
}
|
||||
|
||||
Collections.sort(distribution);
|
||||
//Collections.reverse(distribution);
|
||||
// Collections.reverse(distribution);
|
||||
|
||||
return distribution;
|
||||
}
|
||||
@ -1920,12 +1993,14 @@ public class EditSession {
|
||||
*
|
||||
* @param x
|
||||
* @param z
|
||||
* @param minY minimal height
|
||||
* @param maxY maximal height
|
||||
* @param minY
|
||||
* minimal height
|
||||
* @param maxY
|
||||
* maximal height
|
||||
* @return height of highest block found or 'minY'
|
||||
*/
|
||||
|
||||
public int getHighestTerrainBlock( int x , int z, int minY, int maxY) {
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
|
||||
for (int y = maxY; y >= minY; y--) {
|
||||
Vector pt = new Vector(x, y, z);
|
||||
int id = getBlock(pt).getID();
|
||||
@ -1974,7 +2049,8 @@ public class EditSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockBag the blockBag to set
|
||||
* @param blockBag
|
||||
* the blockBag to set
|
||||
*/
|
||||
public void setBlockBag(BlockBag blockBag) {
|
||||
this.blockBag = blockBag;
|
||||
|
59
src/com/sk89q/worldedit/LocalConfiguration.java
Normale Datei
59
src/com/sk89q/worldedit/LocalConfiguration.java
Normale Datei
@ -0,0 +1,59 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldedit.snapshots.SnapshotRepository;
|
||||
|
||||
/**
|
||||
* Represents WorldEdit's configuration.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class LocalConfiguration {
|
||||
protected static final int[] defaultDisallowedBlocks = new int[] {
|
||||
6, 7, 14, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 39, 31,
|
||||
32, 33, 34, 36, 37, 38, 39, 40, 46, 50, 51, 56, 59, 69, 73, 74,
|
||||
75, 76, 77, 81, 83
|
||||
};
|
||||
|
||||
public boolean profile = false;
|
||||
public Set<Integer> disallowedBlocks = null;
|
||||
public int defaultChangeLimit = -1;
|
||||
public int maxChangeLimit = -1;
|
||||
public String shellSaveType = null;
|
||||
public SnapshotRepository snapshotRepo = null;
|
||||
public int maxRadius = -1;
|
||||
public int maxSuperPickaxeSize = 5;
|
||||
public boolean logComands = false;
|
||||
public boolean registerHelp = true;
|
||||
public int wandItem = 271;
|
||||
public boolean superPickaxeDrop = true;
|
||||
public boolean superPickaxeManyDrop = true;
|
||||
public boolean noDoubleSlash = false;
|
||||
public boolean useInventory = false;
|
||||
public boolean useInventoryOverride = false;
|
||||
|
||||
/**
|
||||
* Loads the configuration.
|
||||
*/
|
||||
public abstract void load();
|
||||
}
|
@ -26,7 +26,7 @@ import com.sk89q.worldedit.blocks.BlockType;
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class WorldEditPlayer {
|
||||
public abstract class LocalPlayer {
|
||||
/**
|
||||
* Directions.
|
||||
*/
|
||||
@ -48,9 +48,11 @@ public abstract class WorldEditPlayer {
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param server
|
||||
*/
|
||||
protected WorldEditPlayer() {
|
||||
server = ServerInterface.getInstance();
|
||||
protected LocalPlayer(ServerInterface server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +74,7 @@ public abstract class WorldEditPlayer {
|
||||
*
|
||||
* @param searchPos search position
|
||||
*/
|
||||
public void findFreePosition(Vector searchPos) {
|
||||
public void findFreePosition(LocalWorld world, Vector searchPos) {
|
||||
int x = searchPos.getBlockX();
|
||||
int y = Math.max(0, searchPos.getBlockY());
|
||||
int origY = y;
|
||||
@ -81,7 +83,8 @@ public abstract class WorldEditPlayer {
|
||||
byte free = 0;
|
||||
|
||||
while (y <= 129) {
|
||||
if (BlockType.canPassThrough(server.getBlockType(new Vector(x, y, z)))) {
|
||||
if (BlockType.canPassThrough(server.getBlockType(world,
|
||||
new Vector(x, y, z)))) {
|
||||
free++;
|
||||
} else {
|
||||
free = 0;
|
||||
@ -106,7 +109,7 @@ public abstract class WorldEditPlayer {
|
||||
* that free position.
|
||||
*/
|
||||
public void findFreePosition() {
|
||||
findFreePosition(getBlockIn());
|
||||
findFreePosition(getPosition().getWorld(), getBlockIn());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,12 +122,13 @@ public abstract class WorldEditPlayer {
|
||||
int x = pos.getBlockX();
|
||||
int y = Math.max(0, pos.getBlockY());
|
||||
int z = pos.getBlockZ();
|
||||
LocalWorld world = getPosition().getWorld();
|
||||
|
||||
byte free = 0;
|
||||
byte spots = 0;
|
||||
|
||||
while (y <= 129) {
|
||||
if (BlockType.canPassThrough(server.getBlockType(new Vector(x, y, z)))) {
|
||||
if (BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) {
|
||||
free++;
|
||||
} else {
|
||||
free = 0;
|
||||
@ -133,7 +137,7 @@ public abstract class WorldEditPlayer {
|
||||
if (free == 2) {
|
||||
spots++;
|
||||
if (spots == 2) {
|
||||
int type = server.getBlockType(new Vector(x, y - 2, z));
|
||||
int type = server.getBlockType(world, new Vector(x, y - 2, z));
|
||||
|
||||
// Don't get put in lava!
|
||||
if (type == 10 || type == 11) {
|
||||
@ -161,11 +165,12 @@ public abstract class WorldEditPlayer {
|
||||
int x = pos.getBlockX();
|
||||
int y = Math.max(0, pos.getBlockY() - 1);
|
||||
int z = pos.getBlockZ();
|
||||
LocalWorld world = getPosition().getWorld();
|
||||
|
||||
byte free = 0;
|
||||
|
||||
while (y >= 1) {
|
||||
if (BlockType.canPassThrough(server.getBlockType(new Vector(x, y, z)))) {
|
||||
if (BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) {
|
||||
free++;
|
||||
} else {
|
||||
free = 0;
|
||||
@ -176,7 +181,7 @@ public abstract class WorldEditPlayer {
|
||||
// lightly and also check to see if there's something to
|
||||
// stand upon
|
||||
while (y >= 0) {
|
||||
int type = server.getBlockType(new Vector(x, y, z));
|
||||
int type = server.getBlockType(world, new Vector(x, y, z));
|
||||
|
||||
// Don't want to end up in lava
|
||||
if (type != 0 && type != 10 && type != 11) {
|
||||
@ -209,17 +214,18 @@ public abstract class WorldEditPlayer {
|
||||
int initialY = Math.max(0, pos.getBlockY());
|
||||
int y = Math.max(0, pos.getBlockY() + 2);
|
||||
int z = pos.getBlockZ();
|
||||
LocalWorld world = getPosition().getWorld();
|
||||
|
||||
// No free space above
|
||||
if (server.getBlockType(new Vector(x, y, z)) != 0) {
|
||||
if (server.getBlockType(world, new Vector(x, y, z)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (y <= 127) {
|
||||
// Found a ceiling!
|
||||
if (!BlockType.canPassThrough(server.getBlockType(new Vector(x, y, z)))) {
|
||||
if (!BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) {
|
||||
int platformY = Math.max(initialY, y - 3 - clearance);
|
||||
server.setBlockType(new Vector(x, platformY, z),
|
||||
server.setBlockType(world, new Vector(x, platformY, z),
|
||||
BlockType.GLASS.getID());
|
||||
setPosition(new Vector(x + 0.5, platformY + 1, z + 0.5));
|
||||
return true;
|
||||
@ -244,14 +250,15 @@ public abstract class WorldEditPlayer {
|
||||
int y = Math.max(0, pos.getBlockY() + 1);
|
||||
int z = pos.getBlockZ();
|
||||
int maxY = Math.min(128, initialY + distance);
|
||||
LocalWorld world = getPosition().getWorld();
|
||||
|
||||
while (y <= 129) {
|
||||
if (!BlockType.canPassThrough(server.getBlockType(new Vector(x, y, z)))) {
|
||||
if (!BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) {
|
||||
break; // Hit something
|
||||
} else if (y > maxY + 1) {
|
||||
break;
|
||||
} else if (y == maxY + 1) {
|
||||
server.setBlockType(new Vector(x, y - 2, z),
|
||||
server.setBlockType(world, new Vector(x, y - 2, z),
|
||||
BlockType.GLASS.getID());
|
||||
setPosition(new Vector(x + 0.5, y - 1, z + 0.5));
|
||||
return true;
|
||||
@ -268,8 +275,8 @@ public abstract class WorldEditPlayer {
|
||||
*
|
||||
* @return point
|
||||
*/
|
||||
public Vector getBlockIn() {
|
||||
return getPosition().toBlockVector();
|
||||
public WorldVector getBlockIn() {
|
||||
return getPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,8 +284,9 @@ public abstract class WorldEditPlayer {
|
||||
*
|
||||
* @return point
|
||||
*/
|
||||
public Vector getBlockOn() {
|
||||
return getPosition().subtract(0, 1, 0).toBlockVector();
|
||||
public WorldVector getBlockOn() {
|
||||
WorldVector pos = getPosition();
|
||||
return new WorldVector(pos.getWorld(), pos.subtract(0, 1, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,7 +295,7 @@ public abstract class WorldEditPlayer {
|
||||
* @param range
|
||||
* @return point
|
||||
*/
|
||||
public abstract Vector getBlockTrace(int range);
|
||||
public abstract WorldVector getBlockTrace(int range);
|
||||
|
||||
/**
|
||||
* Get the point of the block being looked at. May return null.
|
||||
@ -295,14 +303,14 @@ public abstract class WorldEditPlayer {
|
||||
* @param range
|
||||
* @return point
|
||||
*/
|
||||
public abstract Vector getSolidBlockTrace(int range);
|
||||
public abstract WorldVector getSolidBlockTrace(int range);
|
||||
|
||||
/**
|
||||
* Get the player's cardinal direction (N, W, NW, etc.). May return null.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WorldEditPlayer.DIRECTION getCardinalDirection() {
|
||||
public LocalPlayer.DIRECTION getCardinalDirection() {
|
||||
// From hey0's code
|
||||
double rot = (getYaw() - 90) % 360;
|
||||
if (rot < 0) {
|
||||
@ -317,25 +325,25 @@ public abstract class WorldEditPlayer {
|
||||
* @param rot
|
||||
* @return
|
||||
*/
|
||||
private static WorldEditPlayer.DIRECTION getDirection(double rot) {
|
||||
private static LocalPlayer.DIRECTION getDirection(double rot) {
|
||||
if (0 <= rot && rot < 22.5) {
|
||||
return WorldEditPlayer.DIRECTION.NORTH;
|
||||
return LocalPlayer.DIRECTION.NORTH;
|
||||
} else if (22.5 <= rot && rot < 67.5) {
|
||||
return WorldEditPlayer.DIRECTION.NORTH_EAST;
|
||||
return LocalPlayer.DIRECTION.NORTH_EAST;
|
||||
} else if (67.5 <= rot && rot < 112.5) {
|
||||
return WorldEditPlayer.DIRECTION.EAST;
|
||||
return LocalPlayer.DIRECTION.EAST;
|
||||
} else if (112.5 <= rot && rot < 157.5) {
|
||||
return WorldEditPlayer.DIRECTION.SOUTH_EAST;
|
||||
return LocalPlayer.DIRECTION.SOUTH_EAST;
|
||||
} else if (157.5 <= rot && rot < 202.5) {
|
||||
return WorldEditPlayer.DIRECTION.SOUTH;
|
||||
return LocalPlayer.DIRECTION.SOUTH;
|
||||
} else if (202.5 <= rot && rot < 247.5) {
|
||||
return WorldEditPlayer.DIRECTION.SOUTH_WEST;
|
||||
return LocalPlayer.DIRECTION.SOUTH_WEST;
|
||||
} else if (247.5 <= rot && rot < 292.5) {
|
||||
return WorldEditPlayer.DIRECTION.WEST;
|
||||
return LocalPlayer.DIRECTION.WEST;
|
||||
} else if (292.5 <= rot && rot < 337.5) {
|
||||
return WorldEditPlayer.DIRECTION.NORTH_WEST;
|
||||
return LocalPlayer.DIRECTION.NORTH_WEST;
|
||||
} else if (337.5 <= rot && rot < 360.0) {
|
||||
return WorldEditPlayer.DIRECTION.NORTH;
|
||||
return LocalPlayer.DIRECTION.NORTH;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -360,7 +368,14 @@ public abstract class WorldEditPlayer {
|
||||
*
|
||||
* @return point
|
||||
*/
|
||||
public abstract Vector getPosition();
|
||||
public abstract WorldVector getPosition();
|
||||
|
||||
/**
|
||||
* Get the player's world.
|
||||
*
|
||||
* @return point
|
||||
*/
|
||||
public abstract LocalWorld getWorld();
|
||||
|
||||
/**
|
||||
* Get the player's view pitch.
|
||||
@ -463,6 +478,15 @@ public abstract class WorldEditPlayer {
|
||||
*/
|
||||
public abstract boolean hasPermission(String perm);
|
||||
|
||||
/**
|
||||
* Returns true if the player can destroy bedrock.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean canDestroyBedrock() {
|
||||
return hasPermission("worldeditbedrock");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if equal.
|
||||
*
|
||||
@ -471,10 +495,10 @@ public abstract class WorldEditPlayer {
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof WorldEditPlayer)) {
|
||||
if (!(other instanceof LocalPlayer)) {
|
||||
return false;
|
||||
}
|
||||
WorldEditPlayer other2 = (WorldEditPlayer)other;
|
||||
LocalPlayer other2 = (LocalPlayer)other;
|
||||
return other2.getName().equals(getName());
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ package com.sk89q.worldedit;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import com.sk89q.worldedit.snapshots.Snapshot;
|
||||
import com.sk89q.worldedit.superpickaxe.SinglePickaxe;
|
||||
import com.sk89q.worldedit.superpickaxe.SuperPickaxeMode;
|
||||
import com.sk89q.worldedit.bags.BlockBag;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
@ -29,25 +31,9 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldEditSession {
|
||||
/**
|
||||
* List of super pick axe modes.
|
||||
*/
|
||||
public static enum SuperPickaxeMode {
|
||||
SINGLE,
|
||||
SAME_TYPE_RECURSIVE,
|
||||
SAME_TYPE_AREA
|
||||
};
|
||||
/**
|
||||
* List of tools.
|
||||
*/
|
||||
public static enum Tool {
|
||||
NONE,
|
||||
INFO,
|
||||
TREE,
|
||||
}
|
||||
|
||||
public class LocalSession {
|
||||
public static final int MAX_HISTORY_SIZE = 15;
|
||||
|
||||
private boolean placeAtPos1 = false;
|
||||
private Vector pos1, pos2;
|
||||
private Region region;
|
||||
@ -55,10 +41,9 @@ public class WorldEditSession {
|
||||
private int historyPointer = 0;
|
||||
private CuboidClipboard clipboard;
|
||||
private boolean toolControl = true;
|
||||
private boolean superPickAxe = false;
|
||||
private SuperPickaxeMode superPickaxeMode = SuperPickaxeMode.SINGLE;
|
||||
private Tool tool = Tool.NONE;
|
||||
private int superPickaxeRange = 3;
|
||||
private boolean superPickaxe = false;
|
||||
private SuperPickaxeMode superPickaxeMode = new SinglePickaxe();
|
||||
private SuperPickaxeMode tool;
|
||||
private int maxBlocksChanged = -1;
|
||||
private boolean useInventory;
|
||||
private Snapshot snapshot;
|
||||
@ -291,25 +276,25 @@ public class WorldEditSession {
|
||||
* @return status
|
||||
*/
|
||||
public boolean hasSuperPickAxe() {
|
||||
return superPickAxe;
|
||||
return superPickaxe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable super pick axe.
|
||||
*
|
||||
* @param superPickAxe
|
||||
* @param superPickaxe
|
||||
*/
|
||||
public void enableSuperPickAxe() {
|
||||
superPickAxe = true;
|
||||
superPickaxe = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable super pick axe.
|
||||
*
|
||||
* @param superPickAxe
|
||||
* @param superPickaxe
|
||||
*/
|
||||
public void disableSuperPickAxe() {
|
||||
superPickAxe = false;
|
||||
superPickaxe = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,15 +303,15 @@ public class WorldEditSession {
|
||||
* @return status
|
||||
*/
|
||||
public boolean toggleSuperPickAxe() {
|
||||
superPickAxe = !superPickAxe;
|
||||
return superPickAxe;
|
||||
superPickaxe = !superPickaxe;
|
||||
return superPickaxe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return position
|
||||
* @throws IncompleteRegionException
|
||||
*/
|
||||
public Vector getPlacementPosition(WorldEditPlayer player)
|
||||
public Vector getPlacementPosition(LocalPlayer player)
|
||||
throws IncompleteRegionException {
|
||||
if (!placeAtPos1) {
|
||||
return player.getBlockIn();
|
||||
@ -350,7 +335,7 @@ public class WorldEditSession {
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public BlockBag getBlockBag(WorldEditPlayer player) {
|
||||
public BlockBag getBlockBag(LocalPlayer player) {
|
||||
if (!useInventory) {
|
||||
return null;
|
||||
}
|
||||
@ -385,31 +370,17 @@ public class WorldEditSession {
|
||||
this.superPickaxeMode = superPickaxeMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the superPickaxeRange
|
||||
*/
|
||||
public int getSuperPickaxeRange() {
|
||||
return superPickaxeRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param superPickaxeRange the superPickaxeRange to set
|
||||
*/
|
||||
public void setSuperPickaxeRange(int superPickaxeRange) {
|
||||
this.superPickaxeRange = superPickaxeRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tool
|
||||
*/
|
||||
public Tool getTool() {
|
||||
public SuperPickaxeMode getTool() {
|
||||
return tool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tool the tool to set
|
||||
*/
|
||||
public void setTool(Tool tool) {
|
||||
public void setTool(SuperPickaxeMode tool) {
|
||||
this.tool = tool;
|
||||
}
|
||||
|
41
src/com/sk89q/worldedit/LocalWorld.java
Normale Datei
41
src/com/sk89q/worldedit/LocalWorld.java
Normale Datei
@ -0,0 +1,41 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
/**
|
||||
* Represents a world.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class LocalWorld {
|
||||
/**
|
||||
* Compare if the other world is equal.
|
||||
*
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean equals(Object other);
|
||||
/**
|
||||
* Hash code.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract int hashCode();
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
@ -26,28 +26,6 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class ServerInterface {
|
||||
/**
|
||||
* Instance.
|
||||
*/
|
||||
private static ServerInterface instance;
|
||||
|
||||
/**
|
||||
* Get the current instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ServerInterface getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up an instance.
|
||||
* @param instance
|
||||
*/
|
||||
public static void setup(ServerInterface instance) {
|
||||
ServerInterface.instance = instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set block type.
|
||||
*
|
||||
@ -55,7 +33,7 @@ public abstract class ServerInterface {
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean setBlockType(Vector pt, int type);
|
||||
public abstract boolean setBlockType(LocalWorld world, Vector pt, int type);
|
||||
|
||||
/**
|
||||
* Get block type.
|
||||
@ -63,7 +41,7 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public abstract int getBlockType(Vector pt);
|
||||
public abstract int getBlockType(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Set block data.
|
||||
@ -72,7 +50,7 @@ public abstract class ServerInterface {
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public abstract void setBlockData(Vector pt, int data);
|
||||
public abstract void setBlockData(LocalWorld world, Vector pt, int data);
|
||||
|
||||
/**
|
||||
* Get block data.
|
||||
@ -80,7 +58,7 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public abstract int getBlockData(Vector pt);
|
||||
public abstract int getBlockData(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Set sign text.
|
||||
@ -88,7 +66,7 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @param text
|
||||
*/
|
||||
public abstract void setSignText(Vector pt, String[] text);
|
||||
public abstract void setSignText(LocalWorld world, Vector pt, String[] text);
|
||||
|
||||
/**
|
||||
* Get sign text.
|
||||
@ -96,7 +74,7 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public abstract String[] getSignText(Vector pt);
|
||||
public abstract String[] getSignText(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Gets the contents of chests. Will return null if the chest does not
|
||||
@ -105,7 +83,7 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public abstract BaseItemStack[] getChestContents(Vector pt);
|
||||
public abstract BaseItemStack[] getChestContents(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Sets a chest slot.
|
||||
@ -114,14 +92,15 @@ public abstract class ServerInterface {
|
||||
* @param contents
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean setChestContents(Vector pt, BaseItemStack[] contents);
|
||||
public abstract boolean setChestContents(LocalWorld world, Vector pt,
|
||||
BaseItemStack[] contents);
|
||||
|
||||
/**
|
||||
* Clear a chest's contents.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public abstract boolean clearChest(Vector pt);
|
||||
public abstract boolean clearChest(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Checks if a mob type is valid.
|
||||
@ -137,7 +116,8 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @param mobType
|
||||
*/
|
||||
public abstract void setMobSpawnerType(Vector pt, String mobType);
|
||||
public abstract void setMobSpawnerType(LocalWorld world, Vector pt,
|
||||
String mobType);
|
||||
|
||||
/**
|
||||
* Get mob spawner mob type. May return an empty string.
|
||||
@ -145,7 +125,7 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @param mobType
|
||||
*/
|
||||
public abstract String getMobSpawnerType(Vector pt);
|
||||
public abstract String getMobSpawnerType(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Generate a tree at a location.
|
||||
@ -153,7 +133,8 @@ public abstract class ServerInterface {
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean generateTree(EditSession editSession, Vector pt);
|
||||
public abstract boolean generateTree(EditSession editSession,
|
||||
LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Drop an item.
|
||||
@ -163,7 +144,8 @@ public abstract class ServerInterface {
|
||||
* @param count
|
||||
* @param times
|
||||
*/
|
||||
public abstract void dropItem(Vector pt, int type, int count, int times);
|
||||
public abstract void dropItem(LocalWorld world, Vector pt, int type,
|
||||
int count, int times);
|
||||
|
||||
/**
|
||||
* Drop an item.
|
||||
@ -173,7 +155,8 @@ public abstract class ServerInterface {
|
||||
* @param count
|
||||
* @param times
|
||||
*/
|
||||
public abstract void dropItem(Vector pt, int type, int count);
|
||||
public abstract void dropItem(LocalWorld world, Vector pt, int type,
|
||||
int count);
|
||||
|
||||
/**
|
||||
* Drop an item.
|
||||
@ -183,14 +166,14 @@ public abstract class ServerInterface {
|
||||
* @param count
|
||||
* @param times
|
||||
*/
|
||||
public abstract void dropItem(Vector pt, int type);
|
||||
public abstract void dropItem(LocalWorld world, Vector pt, int type);
|
||||
|
||||
/**
|
||||
* Simulate a block being mined.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public abstract void simulateBlockMine(Vector pt);
|
||||
public abstract void simulateBlockMine(LocalWorld world, Vector pt);
|
||||
|
||||
/**
|
||||
* Resolves an item name to its ID.
|
||||
@ -207,5 +190,5 @@ public abstract class ServerInterface {
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
public abstract int killMobs(Vector origin, int radius);
|
||||
public abstract int killMobs(LocalWorld world, Vector origin, int radius);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ package com.sk89q.worldedit;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Albert
|
||||
* @author sk89q
|
||||
*/
|
||||
public class Vector {
|
||||
protected final double x, y, z;
|
||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
104
src/com/sk89q/worldedit/WorldVector.java
Normale Datei
104
src/com/sk89q/worldedit/WorldVector.java
Normale Datei
@ -0,0 +1,104 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
/**
|
||||
* A vector with a world component.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldVector extends Vector {
|
||||
/**
|
||||
* Represents the world.
|
||||
*/
|
||||
private LocalWorld world;
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public WorldVector(LocalWorld world, double x, double y, double z) {
|
||||
super(x, y, z);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public WorldVector(LocalWorld world, int x, int y, int z) {
|
||||
super(x, y, z);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public WorldVector(LocalWorld world, float x, float y, float z) {
|
||||
super(x, y, z);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public WorldVector(LocalWorld world, Vector pt) {
|
||||
super(pt);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*/
|
||||
public WorldVector(LocalWorld world) {
|
||||
super();
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LocalWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a BlockVector version.
|
||||
*
|
||||
* @return BlockWorldVector
|
||||
*/
|
||||
public BlockWorldVector toWorldBlockVector() {
|
||||
return new BlockWorldVector(this);
|
||||
}
|
||||
}
|
94
src/com/sk89q/worldedit/cli/Main.java
Normale Datei
94
src/com/sk89q/worldedit/cli/Main.java
Normale Datei
@ -0,0 +1,94 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.cli;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import java.util.List;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class Main {
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] _args) throws Throwable {
|
||||
OptionParser parser = new OptionParser();
|
||||
OptionSpec<String> world =
|
||||
parser.accepts("world").withRequiredArg().ofType(String.class)
|
||||
.describedAs("world directory").defaultsTo("world");
|
||||
parser.acceptsAll(asList("?", "h"), "show help");
|
||||
|
||||
OptionSet options = parser.parse(_args);
|
||||
List<String> args = options.nonOptionArguments();
|
||||
|
||||
if (args.size() != 1 || options.has("?")) {
|
||||
System.err.println("worldedit <action>");
|
||||
System.err.println();
|
||||
parser.printHelpOn(System.err);
|
||||
return;
|
||||
}
|
||||
|
||||
System.err.println("WorldEdit v" + getVersion());
|
||||
System.err.println("Copyright (c) 2010-2011 sk89q <http://www.sk89q.com>");
|
||||
System.err.println();
|
||||
|
||||
String act = args.get(0);
|
||||
String worldPath = options.valueOf(world);
|
||||
|
||||
if (act.equalsIgnoreCase("check")) {
|
||||
new WorldChecker(worldPath);
|
||||
} else {
|
||||
System.err.println("Only valid action is 'check'.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getVersion() {
|
||||
Package p = com.sk89q.worldedit.cli.Main.class.getPackage();
|
||||
|
||||
if (p == null) {
|
||||
p = Package.getPackage("com.sk89q.worldedit");
|
||||
}
|
||||
|
||||
String version;
|
||||
|
||||
if (p == null) {
|
||||
return "(unknown)";
|
||||
} else {
|
||||
version = p.getImplementationVersion();
|
||||
|
||||
if (version == null) {
|
||||
return "(unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
92
src/com/sk89q/worldedit/cli/WorldChecker.java
Normale Datei
92
src/com/sk89q/worldedit/cli/WorldChecker.java
Normale Datei
@ -0,0 +1,92 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.cli;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jnbt.NBTInputStream;
|
||||
import org.jnbt.Tag;
|
||||
|
||||
public class WorldChecker {
|
||||
private File worldPath;
|
||||
|
||||
public WorldChecker(String path) {
|
||||
worldPath = new File(path);
|
||||
|
||||
checkLevelDat();
|
||||
checkFiles();
|
||||
|
||||
System.out.println("Done.");
|
||||
}
|
||||
|
||||
public void checkLevelDat() {
|
||||
try {
|
||||
checkNBT(new File(worldPath, "level.dat"));
|
||||
} catch (IOException e) {
|
||||
System.out.println("BAD: level.dat: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void checkFiles() {
|
||||
final Pattern chunkFilePattern = Pattern.compile("^c\\..*\\.dat$");
|
||||
|
||||
FileFilter folderFilter = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return f.isDirectory();
|
||||
}
|
||||
};
|
||||
|
||||
FileFilter chunkFilter = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return f.isFile()
|
||||
&& chunkFilePattern.matcher(f.getName()).matches();
|
||||
}
|
||||
};
|
||||
|
||||
for (File l1 : worldPath.listFiles(folderFilter)) {
|
||||
for (File l2 : l1.listFiles(folderFilter)) {
|
||||
for (File chunkFile : l2.listFiles(chunkFilter)) {
|
||||
checkChunkFile(chunkFile,
|
||||
l1.getName(), l2.getName(), chunkFile.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkChunkFile(File f, String a, String b, String c) {
|
||||
String id = a + "/" + b + "/" + c;
|
||||
|
||||
try {
|
||||
checkNBT(f);
|
||||
} catch (IOException e) {
|
||||
System.out.println("BAD: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkNBT(File file) throws IOException {
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
NBTInputStream nbt = new NBTInputStream(stream);
|
||||
Tag tag = nbt.readTag();
|
||||
}
|
||||
}
|
82
src/com/sk89q/worldedit/superpickaxe/AreaPickaxe.java
Normale Datei
82
src/com/sk89q/worldedit/superpickaxe/AreaPickaxe.java
Normale Datei
@ -0,0 +1,82 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
|
||||
/**
|
||||
* A super pickaxe mode that will remove blocks in an area.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class AreaPickaxe implements SuperPickaxeMode {
|
||||
private static final BaseBlock air = new BaseBlock(0);
|
||||
private int range;
|
||||
|
||||
public AreaPickaxe(int range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked) {
|
||||
int ox = clicked.getBlockX();
|
||||
int oy = clicked.getBlockY();
|
||||
int oz = clicked.getBlockZ();
|
||||
int initialType = server.getBlockType(world, clicked);
|
||||
|
||||
if (initialType == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
EditSession editSession = new EditSession(server, world,
|
||||
session.getBlockChangeLimit());
|
||||
|
||||
try {
|
||||
for (int x = ox - range; x <= ox + range; x++) {
|
||||
for (int y = oy - range; y <= oy + range; y++) {
|
||||
for (int z = oz - range; z <= oz + range; z++) {
|
||||
Vector pos = new Vector(x, y, z);
|
||||
if (server.getBlockType(world, pos) == initialType) {
|
||||
if (config.superPickaxeManyDrop) {
|
||||
server.simulateBlockMine(world, pos);
|
||||
}
|
||||
|
||||
editSession.setBlock(pos, air);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached.");
|
||||
} finally {
|
||||
session.remember(editSession);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
54
src/com/sk89q/worldedit/superpickaxe/BlockReplacer.java
Normale Datei
54
src/com/sk89q/worldedit/superpickaxe/BlockReplacer.java
Normale Datei
@ -0,0 +1,54 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
|
||||
/**
|
||||
* A smode that replaces one block.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class BlockReplacer implements SuperPickaxeMode {
|
||||
private BaseBlock targetBlock;
|
||||
|
||||
public BlockReplacer(BaseBlock targetBlock) {
|
||||
this.targetBlock = targetBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked) {
|
||||
|
||||
EditSession editSession = new EditSession(server, world, -1);
|
||||
|
||||
try {
|
||||
editSession.setBlock(clicked, targetBlock);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
} finally {
|
||||
session.remember(editSession);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
52
src/com/sk89q/worldedit/superpickaxe/QueryTool.java
Normale Datei
52
src/com/sk89q/worldedit/superpickaxe/QueryTool.java
Normale Datei
@ -0,0 +1,52 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.*;
|
||||
|
||||
/**
|
||||
* Plants a tree.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class QueryTool implements SuperPickaxeMode {
|
||||
|
||||
@Override
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked) {
|
||||
BaseBlock block = (new EditSession(server, world, 0)).rawGetBlock(clicked);
|
||||
|
||||
player.print("\u00A79@" + clicked + ": " + "\u00A7e"
|
||||
+ "Type: " + block.getID() + "\u00A77" + " ("
|
||||
+ BlockType.fromID(block.getID()).getName() + ") "
|
||||
+ "\u00A7f"
|
||||
+ "[" + block.getData() + "]");
|
||||
|
||||
if (block instanceof MobSpawnerBlock) {
|
||||
player.printRaw("\u00A7e" + "Mob Type: "
|
||||
+ ((MobSpawnerBlock)block).getMobType());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
119
src/com/sk89q/worldedit/superpickaxe/RecursivePickaxe.java
Normale Datei
119
src/com/sk89q/worldedit/superpickaxe/RecursivePickaxe.java
Normale Datei
@ -0,0 +1,119 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
|
||||
/**
|
||||
* A pickaxe mode that recursively finds adjacent blocks within range of
|
||||
* an initial block and of the same type.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class RecursivePickaxe implements SuperPickaxeMode {
|
||||
private static final BaseBlock air = new BaseBlock(0);
|
||||
private int range;
|
||||
|
||||
public RecursivePickaxe(int range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked) {
|
||||
int initialType = server.getBlockType(world, clicked);
|
||||
|
||||
if (initialType == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
EditSession editSession = new EditSession(server, world,
|
||||
session.getBlockChangeLimit());
|
||||
|
||||
try {
|
||||
recurse(server, editSession, world, clicked.toBlockVector(),
|
||||
clicked, range, initialType, new HashSet<BlockVector>(),
|
||||
config.superPickaxeManyDrop);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached.");
|
||||
} finally {
|
||||
session.remember(editSession);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method.
|
||||
*
|
||||
* @param server
|
||||
* @param superPickaxeManyDrop
|
||||
* @param world
|
||||
* @param pos
|
||||
* @param origin
|
||||
* @param size
|
||||
* @param initialType
|
||||
* @param visited
|
||||
*/
|
||||
private void recurse(ServerInterface server, EditSession editSession,
|
||||
LocalWorld world, BlockVector pos,
|
||||
Vector origin, int size, int initialType,
|
||||
Set<BlockVector> visited, boolean drop)
|
||||
throws MaxChangedBlocksException {
|
||||
|
||||
if (origin.distance(pos) > size || visited.contains(pos)) {
|
||||
return;
|
||||
}
|
||||
|
||||
visited.add(pos);
|
||||
|
||||
if (editSession.getBlock(pos).getID() == initialType) {
|
||||
if (drop) {
|
||||
server.simulateBlockMine(world, pos);
|
||||
}
|
||||
editSession.setBlock(pos, air);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(),
|
||||
origin, size, initialType, visited, drop);
|
||||
recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(),
|
||||
origin, size, initialType, visited, drop);
|
||||
recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(),
|
||||
origin, size, initialType, visited, drop);
|
||||
recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(),
|
||||
origin, size, initialType, visited, drop);
|
||||
recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(),
|
||||
origin, size, initialType, visited, drop);
|
||||
recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(),
|
||||
origin, size, initialType, visited, drop);
|
||||
}
|
||||
|
||||
}
|
52
src/com/sk89q/worldedit/superpickaxe/SinglePickaxe.java
Normale Datei
52
src/com/sk89q/worldedit/superpickaxe/SinglePickaxe.java
Normale Datei
@ -0,0 +1,52 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
|
||||
/**
|
||||
* A super pickaxe mode that removes one block.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class SinglePickaxe implements SuperPickaxeMode {
|
||||
@Override
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked) {
|
||||
|
||||
if (server.getBlockType(world, clicked) == BlockID.BEDROCK
|
||||
&& !player.canDestroyBedrock()) {
|
||||
return true;
|
||||
} else if (server.getBlockType(world, clicked) == BlockID.TNT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config.superPickaxeDrop) {
|
||||
server.simulateBlockMine(world, clicked);
|
||||
}
|
||||
|
||||
server.setBlockType(world, clicked, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
42
src/com/sk89q/worldedit/superpickaxe/SuperPickaxeMode.java
Normale Datei
42
src/com/sk89q/worldedit/superpickaxe/SuperPickaxeMode.java
Normale Datei
@ -0,0 +1,42 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
|
||||
/**
|
||||
* Represents a super pickaxe mode.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public interface SuperPickaxeMode {
|
||||
/**
|
||||
* Perform the action. Should return true to deny the default
|
||||
* action.
|
||||
*
|
||||
* @param player
|
||||
* @param session
|
||||
* @param clicked
|
||||
* @return true to deny
|
||||
*/
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked);
|
||||
}
|
49
src/com/sk89q/worldedit/superpickaxe/TreePlanter.java
Normale Datei
49
src/com/sk89q/worldedit/superpickaxe/TreePlanter.java
Normale Datei
@ -0,0 +1,49 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.superpickaxe;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
|
||||
/**
|
||||
* Plants a tree.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class TreePlanter implements SuperPickaxeMode {
|
||||
|
||||
@Override
|
||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session, LocalWorld world,
|
||||
Vector clicked) {
|
||||
EditSession editSession =
|
||||
new EditSession(server, world, session.getBlockChangeLimit());
|
||||
|
||||
try {
|
||||
if (!server.generateTree(editSession, player.getWorld(), clicked)) {
|
||||
player.printError("Notch won't let you put a tree there.");
|
||||
}
|
||||
} finally {
|
||||
session.remember(editSession);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
124
src/joptsimple/AbstractOptionSpec.java
Normale Datei
124
src/joptsimple/AbstractOptionSpec.java
Normale Datei
@ -0,0 +1,124 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* @param <V> represents the type of the arguments this option accepts
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: AbstractOptionSpec.java,v 1.19 2009/11/28 21:31:53 pholser Exp $
|
||||
*/
|
||||
abstract class AbstractOptionSpec<V> implements OptionSpec<V> {
|
||||
private final List<String> options = new ArrayList<String>();
|
||||
private final String description;
|
||||
|
||||
protected AbstractOptionSpec( String option ) {
|
||||
this( singletonList( option ), EMPTY );
|
||||
}
|
||||
|
||||
protected AbstractOptionSpec( Collection<String> options, String description ) {
|
||||
arrangeOptions( options );
|
||||
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public final Collection<String> options() {
|
||||
return unmodifiableCollection( options );
|
||||
}
|
||||
|
||||
public final List<V> values( OptionSet detectedOptions ) {
|
||||
return detectedOptions.valuesOf( this );
|
||||
}
|
||||
|
||||
public final V value( OptionSet detectedOptions ) {
|
||||
return detectedOptions.valueOf( this );
|
||||
}
|
||||
|
||||
abstract List<V> defaultValues();
|
||||
|
||||
String description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
protected abstract V convert( String argument );
|
||||
|
||||
abstract void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
|
||||
String detectedArgument );
|
||||
|
||||
abstract boolean acceptsArguments();
|
||||
|
||||
abstract boolean requiresArgument();
|
||||
|
||||
abstract void accept( OptionSpecVisitor visitor );
|
||||
|
||||
private void arrangeOptions( Collection<String> unarranged ) {
|
||||
if ( unarranged.size() == 1 ) {
|
||||
options.addAll( unarranged );
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> shortOptions = new ArrayList<String>();
|
||||
List<String> longOptions = new ArrayList<String>();
|
||||
|
||||
for ( String each : unarranged ) {
|
||||
if ( each.length() == 1 )
|
||||
shortOptions.add( each );
|
||||
else
|
||||
longOptions.add( each );
|
||||
}
|
||||
|
||||
sort( shortOptions );
|
||||
sort( longOptions );
|
||||
|
||||
options.addAll( shortOptions );
|
||||
options.addAll( longOptions );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object that ) {
|
||||
if ( !( that instanceof AbstractOptionSpec<?> ) )
|
||||
return false;
|
||||
|
||||
AbstractOptionSpec<?> other = (AbstractOptionSpec<?>) that;
|
||||
return options.equals( other.options );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return options.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return options.toString();
|
||||
}
|
||||
}
|
57
src/joptsimple/AlternativeLongOptionSpec.java
Normale Datei
57
src/joptsimple/AlternativeLongOptionSpec.java
Normale Datei
@ -0,0 +1,57 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import static joptsimple.ParserRules.*;
|
||||
|
||||
/**
|
||||
* <p>Represents the <kbd>"-W"</kbd> form of long option specification.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: AlternativeLongOptionSpec.java,v 1.13 2009/09/28 01:12:48 pholser Exp $
|
||||
*/
|
||||
class AlternativeLongOptionSpec extends ArgumentAcceptingOptionSpec<String> {
|
||||
AlternativeLongOptionSpec() {
|
||||
super( singletonList( RESERVED_FOR_EXTENSIONS ), true, "Alternative form of long options" );
|
||||
|
||||
describedAs( "opt=value" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
|
||||
if ( !arguments.hasMore() )
|
||||
throw new OptionMissingRequiredArgumentException( options() );
|
||||
|
||||
arguments.treatNextAsLongOption();
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept( OptionSpecVisitor visitor ) {
|
||||
visitor.visit( this );
|
||||
}
|
||||
}
|
301
src/joptsimple/ArgumentAcceptingOptionSpec.java
Normale Datei
301
src/joptsimple/ArgumentAcceptingOptionSpec.java
Normale Datei
@ -0,0 +1,301 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import joptsimple.internal.ReflectionException;
|
||||
import static joptsimple.internal.Objects.*;
|
||||
import static joptsimple.internal.Reflection.*;
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* <p>Specification of an option that accepts an argument.</p>
|
||||
*
|
||||
* <p>Instances are returned from {@link OptionSpecBuilder} methods to allow the formation
|
||||
* of parser directives as sentences in a "fluent interface" language. For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* parser.accepts( "c" ).withRequiredArg().<strong>ofType( Integer.class )</strong>;
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* <p>If no methods are invoked on an instance of this class, then that instance's option
|
||||
* will treat its argument as a {@link String}.</p>
|
||||
*
|
||||
* @param <V> represents the type of the arguments this option accepts
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ArgumentAcceptingOptionSpec.java,v 1.43 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
public abstract class ArgumentAcceptingOptionSpec<V> extends AbstractOptionSpec<V> {
|
||||
private static final char NIL_VALUE_SEPARATOR = '\u0000';
|
||||
|
||||
private final boolean argumentRequired;
|
||||
private ValueConverter<V> converter;
|
||||
private String argumentDescription = "";
|
||||
private String valueSeparator = String.valueOf( NIL_VALUE_SEPARATOR );
|
||||
private final List<V> defaultValues = new ArrayList<V>();
|
||||
|
||||
ArgumentAcceptingOptionSpec( String option, boolean argumentRequired ) {
|
||||
super( option );
|
||||
|
||||
this.argumentRequired = argumentRequired;
|
||||
}
|
||||
|
||||
ArgumentAcceptingOptionSpec( Collection<String> options, boolean argumentRequired, String description ) {
|
||||
super( options, description );
|
||||
|
||||
this.argumentRequired = argumentRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Specifies a type to which arguments of this spec's option are to be
|
||||
* converted.</p>
|
||||
*
|
||||
* <p>JOpt Simple accepts types that have either:</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>a public static method called {@code valueOf} which accepts a single
|
||||
* argument of type {@link String} and whose return type is the same as the class
|
||||
* on which the method is declared. The {@code java.lang} primitive wrapper
|
||||
* classes have such methods.</li>
|
||||
*
|
||||
* <li>a public constructor which accepts a single argument of type
|
||||
* {@link String}.</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>This class converts arguments using those methods in that order; that is,
|
||||
* {@code valueOf} would be invoked before a one-{@link String}-arg constructor
|
||||
* would.</p>
|
||||
*
|
||||
* <p>Invoking this method will trump any previous calls to this method or to
|
||||
* {@link #withValuesConvertedBy(ValueConverter)}.
|
||||
*
|
||||
* @param <T> represents the runtime class of the desired option argument type
|
||||
* @param argumentType desired type of arguments to this spec's option
|
||||
* @return self, so that the caller can add clauses to the fluent interface sentence
|
||||
* @throws NullPointerException if the type is {@code null}
|
||||
* @throws IllegalArgumentException if the type does not have the standard conversion
|
||||
* methods
|
||||
*/
|
||||
public final <T> ArgumentAcceptingOptionSpec<T> ofType( Class<T> argumentType ) {
|
||||
return withValuesConvertedBy( findConverter( argumentType ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Specifies a converter to use to translate arguments of this spec's option into
|
||||
* Java objects. This is useful when converting to types that do not have the
|
||||
* requisite factory method or constructor for {@link #ofType(Class)}.</p>
|
||||
*
|
||||
* <p>Invoking this method will trump any previous calls to this method or to
|
||||
* {@link #ofType(Class)}.
|
||||
*
|
||||
* @param <T> represents the runtime class of the desired option argument type
|
||||
* @param aConverter the converter to use
|
||||
* @return self, so that the caller can add clauses to the fluent interface sentence
|
||||
* @throws NullPointerException if the converter is {@code null}
|
||||
*/
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public final <T> ArgumentAcceptingOptionSpec<T> withValuesConvertedBy( ValueConverter<T> aConverter ) {
|
||||
if ( aConverter == null )
|
||||
throw new NullPointerException( "illegal null converter" );
|
||||
|
||||
converter = (ValueConverter<V>) aConverter;
|
||||
return (ArgumentAcceptingOptionSpec<T>) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Specifies a description for the argument of the option that this spec
|
||||
* represents. This description is used when generating help information about
|
||||
* the parser.</p>
|
||||
*
|
||||
* @param description describes the nature of the argument of this spec's
|
||||
* option
|
||||
* @return self, so that the caller can add clauses to the fluent interface sentence
|
||||
*/
|
||||
public final ArgumentAcceptingOptionSpec<V> describedAs( String description ) {
|
||||
argumentDescription = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Specifies a value separator for the argument of the option that this spec
|
||||
* represents. This allows a single option argument to represent multiple values
|
||||
* for the option. For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* parser.accepts( "z" ).withRequiredArg()
|
||||
* .<strong>withValuesSeparatedBy( ',' )</strong>;
|
||||
* OptionSet options = parser.parse( new String[] { "-z", "foo,bar,baz", "-z",
|
||||
* "fizz", "-z", "buzz" } );
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* <p>Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar,
|
||||
* baz, fizz, buzz]}.</p>
|
||||
*
|
||||
* <p>You cannot use Unicode U+0000 as the separator.</p>
|
||||
*
|
||||
* @param separator a character separator
|
||||
* @return self, so that the caller can add clauses to the fluent interface sentence
|
||||
* @throws IllegalArgumentException if the separator is Unicode U+0000
|
||||
*/
|
||||
public final ArgumentAcceptingOptionSpec<V> withValuesSeparatedBy( char separator ) {
|
||||
if ( separator == NIL_VALUE_SEPARATOR )
|
||||
throw new IllegalArgumentException( "cannot use U+0000 as separator" );
|
||||
|
||||
valueSeparator = String.valueOf( separator );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Specifies a set of default values for the argument of the option that this spec
|
||||
* represents.</p>
|
||||
*
|
||||
* @param value the first in the set of default argument values for this spec's option
|
||||
* @param values the (optional) remainder of the set of default argument values for this spec's option
|
||||
* @return self, so that the caller can add clauses to the fluent interface sentence
|
||||
* @throws NullPointerException if {@code value}, {@code values}, or any elements of {@code values} are
|
||||
* {@code null}
|
||||
*/
|
||||
public ArgumentAcceptingOptionSpec<V> defaultsTo( V value, V... values ) {
|
||||
addDefaultValue( value );
|
||||
for ( V each : values )
|
||||
addDefaultValue( each );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addDefaultValue( V value ) {
|
||||
ensureNotNull( value );
|
||||
defaultValues.add( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
final void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
|
||||
String detectedArgument ) {
|
||||
|
||||
if ( isNullOrEmpty( detectedArgument ) )
|
||||
detectOptionArgument( parser, arguments, detectedOptions );
|
||||
else
|
||||
addArguments( detectedOptions, detectedArgument );
|
||||
}
|
||||
|
||||
protected void addArguments( OptionSet detectedOptions, String detectedArgument ) {
|
||||
StringTokenizer lexer = new StringTokenizer( detectedArgument, valueSeparator );
|
||||
if ( !lexer.hasMoreTokens() )
|
||||
detectedOptions.addWithArgument( this, detectedArgument );
|
||||
else {
|
||||
while ( lexer.hasMoreTokens() )
|
||||
detectedOptions.addWithArgument( this, lexer.nextToken() );
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void detectOptionArgument( OptionParser parser, ArgumentList arguments,
|
||||
OptionSet detectedOptions );
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
@Override
|
||||
protected final V convert( String argument ) {
|
||||
if ( converter == null )
|
||||
return (V) argument;
|
||||
|
||||
try {
|
||||
return converter.convert( argument );
|
||||
}
|
||||
catch ( ReflectionException ex ) {
|
||||
throw new OptionArgumentConversionException( options(), argument, converter.valueType(), ex );
|
||||
}
|
||||
catch ( ValueConversionException ex ) {
|
||||
throw new OptionArgumentConversionException( options(), argument, converter.valueType(), ex );
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canConvertArgument( String argument ) {
|
||||
StringTokenizer lexer = new StringTokenizer( argument, valueSeparator );
|
||||
|
||||
try {
|
||||
while ( lexer.hasMoreTokens() )
|
||||
convert( lexer.nextToken() );
|
||||
return true;
|
||||
}
|
||||
catch ( OptionException ignored ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isArgumentOfNumberType() {
|
||||
return converter != null && Number.class.isAssignableFrom( converter.valueType() );
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean acceptsArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean requiresArgument() {
|
||||
return argumentRequired;
|
||||
}
|
||||
|
||||
String argumentDescription() {
|
||||
return argumentDescription;
|
||||
}
|
||||
|
||||
String typeIndicator() {
|
||||
if ( converter == null )
|
||||
return null;
|
||||
|
||||
String pattern = converter.valuePattern();
|
||||
return pattern == null ? converter.valueType().getName() : pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<V> defaultValues() {
|
||||
return unmodifiableList( defaultValues );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object that ) {
|
||||
if ( !super.equals( that ) )
|
||||
return false;
|
||||
|
||||
ArgumentAcceptingOptionSpec<?> other = (ArgumentAcceptingOptionSpec<?>) that;
|
||||
return requiresArgument() == other.requiresArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ ( argumentRequired ? 0 : 1 );
|
||||
}
|
||||
}
|
60
src/joptsimple/ArgumentList.java
Normale Datei
60
src/joptsimple/ArgumentList.java
Normale Datei
@ -0,0 +1,60 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import static joptsimple.ParserRules.*;
|
||||
|
||||
/**
|
||||
* <p>Wrapper for an array of command line arguments.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ArgumentList.java,v 1.7 2009/08/13 00:34:35 pholser Exp $
|
||||
*/
|
||||
class ArgumentList {
|
||||
private final String[] arguments;
|
||||
private int currentIndex;
|
||||
|
||||
ArgumentList( String... arguments ) {
|
||||
this.arguments = arguments.clone();
|
||||
}
|
||||
|
||||
boolean hasMore() {
|
||||
return currentIndex < arguments.length;
|
||||
}
|
||||
|
||||
String next() {
|
||||
return arguments[ currentIndex++ ];
|
||||
}
|
||||
|
||||
String peek() {
|
||||
return arguments[ currentIndex ];
|
||||
}
|
||||
|
||||
void treatNextAsLongOption() {
|
||||
if ( HYPHEN_CHAR != arguments[ currentIndex ].charAt( 0 ) )
|
||||
arguments[ currentIndex ] = DOUBLE_HYPHEN + arguments[ currentIndex ];
|
||||
}
|
||||
}
|
149
src/joptsimple/HelpFormatter.java
Normale Datei
149
src/joptsimple/HelpFormatter.java
Normale Datei
@ -0,0 +1,149 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import joptsimple.internal.ColumnarData;
|
||||
import static joptsimple.ParserRules.*;
|
||||
import static joptsimple.internal.Classes.*;
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* <p>Produces text for a help screen given a set of options.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: HelpFormatter.java,v 1.19 2009/10/04 00:13:41 pholser Exp $
|
||||
*/
|
||||
class HelpFormatter implements OptionSpecVisitor {
|
||||
private final ColumnarData grid;
|
||||
|
||||
HelpFormatter() {
|
||||
grid = new ColumnarData( "Option", "Description" );
|
||||
}
|
||||
|
||||
String format( Map<String, AbstractOptionSpec<?>> options ) {
|
||||
if ( options.isEmpty() )
|
||||
return "No options specified";
|
||||
|
||||
grid.clear();
|
||||
|
||||
Comparator<AbstractOptionSpec<?>> comparator =
|
||||
new Comparator<AbstractOptionSpec<?>>() {
|
||||
public int compare( AbstractOptionSpec<?> first, AbstractOptionSpec<?> second ) {
|
||||
return first.options().iterator().next().compareTo( second.options().iterator().next() );
|
||||
}
|
||||
};
|
||||
|
||||
Set<AbstractOptionSpec<?>> sorted = new TreeSet<AbstractOptionSpec<?>>( comparator );
|
||||
sorted.addAll( options.values() );
|
||||
|
||||
for ( AbstractOptionSpec<?> each : sorted )
|
||||
each.accept( this );
|
||||
|
||||
return grid.format();
|
||||
}
|
||||
|
||||
void addHelpLineFor( AbstractOptionSpec<?> spec, String additionalInfo ) {
|
||||
grid.addRow( createOptionDisplay( spec ) + additionalInfo, createDescriptionDisplay( spec ) );
|
||||
}
|
||||
|
||||
public void visit( NoArgumentOptionSpec spec ) {
|
||||
addHelpLineFor( spec, "" );
|
||||
}
|
||||
|
||||
public void visit( RequiredArgumentOptionSpec<?> spec ) {
|
||||
visit( spec, '<', '>' );
|
||||
}
|
||||
|
||||
public void visit( OptionalArgumentOptionSpec<?> spec ) {
|
||||
visit( spec, '[', ']' );
|
||||
}
|
||||
|
||||
public void visit( AlternativeLongOptionSpec spec ) {
|
||||
addHelpLineFor( spec, ' ' + surround( spec.argumentDescription(), '<', '>' ) );
|
||||
}
|
||||
|
||||
private void visit( ArgumentAcceptingOptionSpec<?> spec, char begin, char end ) {
|
||||
String argDescription = spec.argumentDescription();
|
||||
String typeIndicator = typeIndicator( spec );
|
||||
StringBuilder collector = new StringBuilder();
|
||||
|
||||
if ( typeIndicator.length() > 0 ) {
|
||||
collector.append( typeIndicator );
|
||||
|
||||
if ( argDescription.length() > 0 )
|
||||
collector.append( ": " ).append( argDescription );
|
||||
}
|
||||
else if ( argDescription.length() > 0 )
|
||||
collector.append( argDescription );
|
||||
|
||||
String helpLine = collector.length() == 0
|
||||
? ""
|
||||
: ' ' + surround( collector.toString(), begin, end );
|
||||
addHelpLineFor( spec, helpLine );
|
||||
}
|
||||
|
||||
private String createOptionDisplay( AbstractOptionSpec<?> spec ) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
for ( Iterator<String> iter = spec.options().iterator(); iter.hasNext(); ) {
|
||||
String option = iter.next();
|
||||
buffer.append( option.length() > 1 ? DOUBLE_HYPHEN : HYPHEN );
|
||||
buffer.append( option );
|
||||
|
||||
if ( iter.hasNext() )
|
||||
buffer.append( ", " );
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private String createDescriptionDisplay( AbstractOptionSpec<?> spec ) {
|
||||
List<?> defaultValues = spec.defaultValues();
|
||||
if ( defaultValues.isEmpty() )
|
||||
return spec.description();
|
||||
|
||||
String defaultValuesDisplay = createDefaultValuesDisplay( defaultValues );
|
||||
return spec.description() + ' ' + surround( "default: " + defaultValuesDisplay, '(', ')' );
|
||||
}
|
||||
|
||||
private String createDefaultValuesDisplay( List<?> defaultValues ) {
|
||||
return defaultValues.size() == 1 ? defaultValues.get( 0 ).toString() : defaultValues.toString();
|
||||
}
|
||||
|
||||
private static String typeIndicator( ArgumentAcceptingOptionSpec<?> spec ) {
|
||||
String indicator = spec.typeIndicator();
|
||||
return indicator == null || String.class.getName().equals( indicator )
|
||||
? ""
|
||||
: shortNameOf( indicator );
|
||||
}
|
||||
}
|
48
src/joptsimple/IllegalOptionClusterException.java
Normale Datei
48
src/joptsimple/IllegalOptionClusterException.java
Normale Datei
@ -0,0 +1,48 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
/**
|
||||
* <p>Thrown when the option parser discovers a cluster of short options in which
|
||||
* at least one of the short options can accept arguments.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: IllegalOptionClusterException.java,v 1.11 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class IllegalOptionClusterException extends OptionException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
IllegalOptionClusterException( String option ) {
|
||||
super( singletonList( option ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Option cluster containing " + singleOptionMessage() + " is illegal";
|
||||
}
|
||||
}
|
48
src/joptsimple/IllegalOptionSpecificationException.java
Normale Datei
48
src/joptsimple/IllegalOptionSpecificationException.java
Normale Datei
@ -0,0 +1,48 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
/**
|
||||
* <p>Thrown when the option parser is asked to recognize an option with illegal
|
||||
* characters in it.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: IllegalOptionSpecificationException.java,v 1.11 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class IllegalOptionSpecificationException extends OptionException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
IllegalOptionSpecificationException( String option ) {
|
||||
super( singletonList( option ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return singleOptionMessage() + " is not a legal option character";
|
||||
}
|
||||
}
|
48
src/joptsimple/MultipleArgumentsForOptionException.java
Normale Datei
48
src/joptsimple/MultipleArgumentsForOptionException.java
Normale Datei
@ -0,0 +1,48 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>Thrown when asking an {@link OptionSet} for a single argument of an option when
|
||||
* many have been specified.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: MultipleArgumentsForOptionException.java,v 1.14 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class MultipleArgumentsForOptionException extends OptionException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
MultipleArgumentsForOptionException( Collection<String> options ) {
|
||||
super( options );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Found multiple arguments for option " + multipleOptionMessage() + ", but you asked for only one";
|
||||
}
|
||||
}
|
79
src/joptsimple/NoArgumentOptionSpec.java
Normale Datei
79
src/joptsimple/NoArgumentOptionSpec.java
Normale Datei
@ -0,0 +1,79 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
/**
|
||||
* <p>A specification for an option that does not accept arguments.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: NoArgumentOptionSpec.java,v 1.16 2009/10/04 00:13:41 pholser Exp $
|
||||
*/
|
||||
class NoArgumentOptionSpec extends AbstractOptionSpec<Void> {
|
||||
NoArgumentOptionSpec( String option ) {
|
||||
this( singletonList( option ), "" );
|
||||
}
|
||||
|
||||
NoArgumentOptionSpec( Collection<String> options, String description ) {
|
||||
super( options, description );
|
||||
}
|
||||
|
||||
@Override
|
||||
void handleOption( OptionParser parser, ArgumentList arguments,
|
||||
OptionSet detectedOptions, String detectedArgument ) {
|
||||
|
||||
detectedOptions.add( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean acceptsArguments() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean requiresArgument() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept( OptionSpecVisitor visitor ) {
|
||||
visitor.visit( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void convert( String argument ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Void> defaultValues() {
|
||||
return emptyList();
|
||||
}
|
||||
}
|
56
src/joptsimple/OptionArgumentConversionException.java
Normale Datei
56
src/joptsimple/OptionArgumentConversionException.java
Normale Datei
@ -0,0 +1,56 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>Thrown when a problem occurs converting an argument of an option from {@link String}
|
||||
* to another type.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionArgumentConversionException.java,v 1.16 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class OptionArgumentConversionException extends OptionException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
private final String argument;
|
||||
private final Class<?> valueType;
|
||||
|
||||
OptionArgumentConversionException( Collection<String> options, String argument, Class<?> valueType,
|
||||
Throwable cause ) {
|
||||
|
||||
super( options, cause );
|
||||
|
||||
this.argument = argument;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Cannot convert argument '" + argument + "' of option " + multipleOptionMessage() + " to " + valueType;
|
||||
}
|
||||
}
|
95
src/joptsimple/OptionException.java
Normale Datei
95
src/joptsimple/OptionException.java
Normale Datei
@ -0,0 +1,95 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* <p>Thrown when a problem occurs during option parsing.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionException.java,v 1.21 2009/08/13 00:34:35 pholser Exp $
|
||||
*/
|
||||
public abstract class OptionException extends RuntimeException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
private final List<String> options = new ArrayList<String>();
|
||||
|
||||
protected OptionException( Collection<String> options ) {
|
||||
this.options.addAll( options );
|
||||
}
|
||||
|
||||
protected OptionException( Collection<String> options, Throwable cause ) {
|
||||
super( cause );
|
||||
|
||||
this.options.addAll( options );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gives the option being considered when the exception was created.</p>
|
||||
*
|
||||
* @return the option being considered when the exception was created
|
||||
*/
|
||||
public Collection<String> options() {
|
||||
return unmodifiableCollection( options );
|
||||
}
|
||||
|
||||
protected final String singleOptionMessage() {
|
||||
return singleOptionMessage( options.get( 0 ) );
|
||||
}
|
||||
|
||||
protected final String singleOptionMessage( String option ) {
|
||||
return SINGLE_QUOTE + option + SINGLE_QUOTE;
|
||||
}
|
||||
|
||||
protected final String multipleOptionMessage() {
|
||||
StringBuilder buffer = new StringBuilder( "[" );
|
||||
|
||||
for ( Iterator<String> iter = options.iterator(); iter.hasNext(); ) {
|
||||
buffer.append( singleOptionMessage( iter.next() ) );
|
||||
if ( iter.hasNext() )
|
||||
buffer.append( ", " );
|
||||
}
|
||||
|
||||
buffer.append( ']' );
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
static OptionException illegalOptionCluster( String option ) {
|
||||
return new IllegalOptionClusterException( option );
|
||||
}
|
||||
|
||||
static OptionException unrecognizedOption( String option ) {
|
||||
return new UnrecognizedOptionException( option );
|
||||
}
|
||||
}
|
48
src/joptsimple/OptionMissingRequiredArgumentException.java
Normale Datei
48
src/joptsimple/OptionMissingRequiredArgumentException.java
Normale Datei
@ -0,0 +1,48 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>Thrown when the option parser discovers an option that requires an argument,
|
||||
* but that argument is missing.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionMissingRequiredArgumentException.java,v 1.12 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class OptionMissingRequiredArgumentException extends OptionException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
OptionMissingRequiredArgumentException( Collection<String> options ) {
|
||||
super( options );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Option " + multipleOptionMessage() + " requires an argument";
|
||||
}
|
||||
}
|
496
src/joptsimple/OptionParser.java
Normale Datei
496
src/joptsimple/OptionParser.java
Normale Datei
@ -0,0 +1,496 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import joptsimple.internal.AbbreviationMap;
|
||||
import joptsimple.util.KeyValuePair;
|
||||
import static joptsimple.OptionException.*;
|
||||
import static joptsimple.OptionParserState.*;
|
||||
import static joptsimple.ParserRules.*;
|
||||
|
||||
/**
|
||||
* <p>Parses command line arguments, using a syntax that attempts to take from the best
|
||||
* of POSIX {@code getopt()} and GNU {@code getopt_long()}.</p>
|
||||
*
|
||||
* <p>This parser supports short options and long options.</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li><dfn>Short options</dfn> begin with a single hyphen ("<kbd>-</kbd>") followed
|
||||
* by a single letter or digit, or question mark ("<kbd>?</kbd>"), or dot
|
||||
* ("<kbd>.</kbd>").</li>
|
||||
*
|
||||
* <li>Short options can accept single arguments. The argument can be made required or
|
||||
* optional. The option's argument can occur:
|
||||
* <ul>
|
||||
* <li>in the slot after the option, as in <kbd>-d /tmp</kbd></li>
|
||||
* <li>right up against the option, as in <kbd>-d/tmp</kbd></li>
|
||||
* <li>right up against the option separated by an equals sign (<kbd>"="</kbd>),
|
||||
* as in <kbd>-d=/tmp</kbd></li>
|
||||
* </ul>
|
||||
* To specify <var>n</var> arguments for an option, specify the option <var>n</var>
|
||||
* times, once for each argument, as in <kbd>-d /tmp -d /var -d /opt</kbd>; or, when
|
||||
* using the {@linkplain ArgumentAcceptingOptionSpec#withValuesSeparatedBy(char)
|
||||
* "separated values"} clause of the "fluent interface" (see below), give multiple
|
||||
* values separated by a given character as a single argument to the option.</li>
|
||||
*
|
||||
* <li>Short options can be clustered, so that <kbd>-abc</kbd> is treated as
|
||||
* <kbd>-a -b -c</kbd>, if none of those options can accept arguments.</li>
|
||||
*
|
||||
* <li>An argument consisting only of two hyphens (<kbd>"--"</kbd>) signals that the
|
||||
* remaining arguments are to be treated as non-options.</li>
|
||||
*
|
||||
* <li>An argument consisting only of a single hyphen is considered a non-option
|
||||
* argument (though it can be an argument of an option). Many Unix programs treat
|
||||
* single hyphens as stand-ins for the standard input or standard output streams.</li>
|
||||
*
|
||||
* <li><dfn>Long options</dfn> begin with two hyphens (<kbd>"--"</kbd>), followed
|
||||
* by multiple letters, digits, hyphens, question marks, or dots. A hyphen cannot be
|
||||
* the first character of a long option specification when configuring the parser.</li>
|
||||
*
|
||||
* <li>You can abbreviate long options, so long as the abbreviation is unique.</li>
|
||||
*
|
||||
* <li>Long options can accept single arguments. The argument can be made required or
|
||||
* optional. The option's argument can occur:
|
||||
* <ul>
|
||||
* <li>in the slot after the option, as in <kbd>--directory /tmp</kbd></li>
|
||||
* <li>right up against the option separated by an equals sign (<kbd>"="</kbd>),
|
||||
* as in <kbd>--directory=/tmp</kbd>
|
||||
* </ul>
|
||||
* Specify multiple arguments for a long option in the same manner as for short options
|
||||
* (see above).</li>
|
||||
*
|
||||
* <li>You can use a single hyphen (<kbd>"-"</kbd>) instead of a double hyphen
|
||||
* (<kbd>"--"</kbd>) for a long option.</li>
|
||||
*
|
||||
* <li>The option <kbd>-W</kbd> is reserved. If you tell the parser to {@linkplain
|
||||
* #recognizeAlternativeLongOptions(boolean) recognize alternative long options}, then
|
||||
* it will treat, for example, <kbd>-W foo=bar</kbd> as the long option
|
||||
* <kbd>foo</kbd> with argument <kbd>bar</kbd>, as though you had written
|
||||
* <kbd>--foo=bar</kbd>.</li>
|
||||
*
|
||||
* <li>You can specify <kbd>-W</kbd> as a valid short option, or use it as an
|
||||
* abbreviation for a long option, but {@linkplain
|
||||
* #recognizeAlternativeLongOptions(boolean) recognizing alternative long options} will
|
||||
* always supersede this behavior.</li>
|
||||
*
|
||||
* <li>You can specify a given short or long option multiple times on a single command
|
||||
* line. The parser collects any arguments specified for those options as a list.</li>
|
||||
*
|
||||
* <li>If the parser detects an option whose argument is optional, and the next argument
|
||||
* "looks like" an option, that argument is not treated as the argument to the option,
|
||||
* but as a potentially valid option. If, on the other hand, the optional argument is
|
||||
* typed as a derivative of {@link Number}, then that argument is treated as the
|
||||
* negative number argument of the option, even if the parser recognizes the
|
||||
* corresponding numeric option. For example:
|
||||
* <pre><code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* parser.accepts( "a" ).withOptionalArg().ofType( Integer.class );
|
||||
* parser.accepts( "2" );
|
||||
* OptionSet options = parser.parse( "-a", "-2" );
|
||||
* </code></pre>
|
||||
* In this case, the option set contains <kbd>"a"</kbd> with argument <kbd>-2</kbd>,
|
||||
* not both <kbd>"a"</kbd> and <kbd>"2"</kbd>. Swapping the elements in the
|
||||
* <var>args</var> array gives the latter.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>There are two ways to tell the parser what options to recognize:</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>A "fluent interface"-style API for specifying options, available since
|
||||
* version 2. Sentences in this fluent interface language begin with a call to
|
||||
* {@link #accepts(String) accepts} or {@link #acceptsAll(Collection) acceptsAll}
|
||||
* methods; calls on the ensuing chain of objects describe whether the options can take
|
||||
* an argument, whether the argument is required or optional, to what type arguments of
|
||||
* the options should be converted if any, etc. Since version 3, these calls return
|
||||
* an instance of {@link OptionSpec}, which can subsequently be used to retrieve the
|
||||
* arguments of the associated option in a type-safe manner.</li>
|
||||
*
|
||||
* <li>Since version 1, a more concise way of specifying short options has been to use
|
||||
* the special {@linkplain #OptionParser(String) constructor}. Arguments of options
|
||||
* specified in this manner will be of type {@link String}. Here are the rules for the
|
||||
* format of the specification strings this constructor accepts:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Any letter or digit is treated as an option character.</li>
|
||||
*
|
||||
* <li>If an option character is followed by a single colon (<kbd>":"</kbd>),
|
||||
* then the option requires an argument.</li>
|
||||
*
|
||||
* <li>If an option character is followed by two colons (<kbd>"::"</kbd>), then
|
||||
* the option accepts an optional argument.</li>
|
||||
*
|
||||
* <li>Otherwise, the option character accepts no argument.</li>
|
||||
*
|
||||
* <li>If the option specification string begins with a plus sign (<kbd>"+"</kbd>),
|
||||
* the parser will behave "POSIX-ly correct".</li>
|
||||
*
|
||||
* <li>If the option specification string contains the sequence <kbd>"W;"</kbd>
|
||||
* (capital W followed by a semicolon), the parser will recognize the alternative
|
||||
* form of long options.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>Each of the options in a list of options given to {@link #acceptsAll(Collection)
|
||||
* acceptsAll} is treated as a synonym of the others. For example:
|
||||
* <pre>
|
||||
* <code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* parser.acceptsAll( asList( "w", "interactive", "confirmation" ) );
|
||||
* OptionSet options = parser.parse( "-w" );
|
||||
* </code>
|
||||
* </pre>
|
||||
* In this case, <code>options.{@link OptionSet#has(String) has}</code> would answer
|
||||
* {@code true} when given arguments <kbd>"w"</kbd>, <kbd>"interactive"</kbd>, and
|
||||
* <kbd>"confirmation"</kbd>. The {@link OptionSet} would give the same responses to
|
||||
* these arguments for its other methods as well.</p>
|
||||
*
|
||||
* <p>By default, as with GNU {@code getopt()}, the parser allows intermixing of options
|
||||
* and non-options. If, however, the parser has been created to be "POSIX-ly correct",
|
||||
* then the first argument that does not look lexically like an option, and is not a
|
||||
* required argument of a preceding option, signals the end of options. You can still
|
||||
* bind optional arguments to their options using the abutting (for short options) or
|
||||
* <kbd>=</kbd> syntax.</p>
|
||||
*
|
||||
* <p>Unlike GNU {@code getopt()}, this parser does not honor the environment variable
|
||||
* {@code POSIXLY_CORRECT}. "POSIX-ly correct" parsers are configured by either:</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>using the method {@link #posixlyCorrect(boolean)}, or</li>
|
||||
*
|
||||
* <li>using the {@linkplain #OptionParser(String) constructor} with an argument whose
|
||||
* first character is a plus sign (<kbd>"+"</kbd>)</li>
|
||||
* </ol>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionParser.java,v 1.38 2009/10/25 18:37:06 pholser Exp $
|
||||
* @see <a href="http://www.gnu.org/software/libc/manual">The GNU C Library </a>
|
||||
*/
|
||||
public class OptionParser {
|
||||
private final AbbreviationMap<AbstractOptionSpec<?>> recognizedOptions;
|
||||
private OptionParserState state;
|
||||
private boolean posixlyCorrect;
|
||||
|
||||
/**
|
||||
* <p>Creates an option parser that initially recognizes no options, and does not
|
||||
* exhibit "POSIX-ly correct" behavior.</p>
|
||||
*/
|
||||
public OptionParser() {
|
||||
recognizedOptions = new AbbreviationMap<AbstractOptionSpec<?>>();
|
||||
state = moreOptions( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates an option parser and configures it to recognize the short options
|
||||
* specified in the given string.</p>
|
||||
*
|
||||
* <p>Arguments of options specified this way will be of type {@link String}.</p>
|
||||
*
|
||||
* @param optionSpecification an option specification
|
||||
* @throws NullPointerException if <var>optionSpecification</var> is
|
||||
* {@code null}
|
||||
* @throws OptionException if the option specification contains illegal characters
|
||||
* or otherwise cannot be recognized
|
||||
*/
|
||||
public OptionParser( String optionSpecification ) {
|
||||
this();
|
||||
|
||||
new OptionSpecTokenizer( optionSpecification ).configure( this );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells the parser to recognize the given option.</p>
|
||||
*
|
||||
* <p>This method returns an instance of {@link OptionSpecBuilder} to allow the
|
||||
* formation of parser directives as sentences in a fluent interface language.
|
||||
* For example:</p>
|
||||
*
|
||||
* <pre><code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* parser.<strong>accepts( "c" )</strong>.withRequiredArg().ofType( Integer.class );
|
||||
* </code></pre>
|
||||
*
|
||||
* <p>If no methods are invoked on the returned {@link OptionSpecBuilder}, then the
|
||||
* parser treats the option as accepting no argument.</p>
|
||||
*
|
||||
* @param option the option to recognize
|
||||
* @return an object that can be used to flesh out more detail about the option
|
||||
* @throws OptionException if the option contains illegal characters
|
||||
* @throws NullPointerException if the option is {@code null}
|
||||
*/
|
||||
public OptionSpecBuilder accepts( String option ) {
|
||||
return acceptsAll( singletonList( option ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells the parser to recognize the given option.</p>
|
||||
*
|
||||
* @see #accepts(String)
|
||||
* @param option the option to recognize
|
||||
* @param description a string that describes the purpose of the option. This is
|
||||
* used when generating help information about the parser.
|
||||
* @return an object that can be used to flesh out more detail about the option
|
||||
* @throws OptionException if the option contains illegal characters
|
||||
* @throws NullPointerException if the option is {@code null}
|
||||
*/
|
||||
public OptionSpecBuilder accepts( String option, String description ) {
|
||||
return acceptsAll( singletonList( option ), description );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells the parser to recognize the given options, and treat them as
|
||||
* synonymous.</p>
|
||||
*
|
||||
* @see #accepts(String)
|
||||
* @param options the options to recognize and treat as synonymous
|
||||
* @return an object that can be used to flesh out more detail about the options
|
||||
* @throws OptionException if any of the options contain illegal characters
|
||||
* @throws NullPointerException if the option list or any of its elements are
|
||||
* {@code null}
|
||||
*/
|
||||
public OptionSpecBuilder acceptsAll( Collection<String> options ) {
|
||||
return acceptsAll( options, "" );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells the parser to recognize the given options, and treat them as
|
||||
* synonymous.</p>
|
||||
*
|
||||
* @see #acceptsAll(Collection)
|
||||
* @param options the options to recognize and treat as synonymous
|
||||
* @param description a string that describes the purpose of the option. This is
|
||||
* used when generating help information about the parser.
|
||||
* @return an object that can be used to flesh out more detail about the options
|
||||
* @throws OptionException if any of the options contain illegal characters
|
||||
* @throws NullPointerException if the option list or any of its elements are
|
||||
* {@code null}
|
||||
* @throws IllegalArgumentException if the option list is empty
|
||||
*/
|
||||
public OptionSpecBuilder acceptsAll( Collection<String> options,
|
||||
String description ) {
|
||||
|
||||
if ( options.isEmpty() )
|
||||
throw new IllegalArgumentException( "need at least one option" );
|
||||
|
||||
ensureLegalOptions( options );
|
||||
|
||||
return new OptionSpecBuilder( this, options, description );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells the parser whether or not to behave "POSIX-ly correct"-ly.</p>
|
||||
*
|
||||
* @param setting {@code true} if the parser should behave "POSIX-ly correct"-ly
|
||||
*/
|
||||
public void posixlyCorrect( boolean setting ) {
|
||||
posixlyCorrect = setting;
|
||||
state = moreOptions( setting );
|
||||
}
|
||||
|
||||
boolean posixlyCorrect() {
|
||||
return posixlyCorrect;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells the parser either to recognize or ignore <kbd>"-W"</kbd>-style long
|
||||
* options.</p>
|
||||
*
|
||||
* @param recognize {@code true} if the parser is to recognize the special style
|
||||
* of long options
|
||||
*/
|
||||
public void recognizeAlternativeLongOptions( boolean recognize ) {
|
||||
if ( recognize )
|
||||
recognize( new AlternativeLongOptionSpec() );
|
||||
else
|
||||
recognizedOptions.remove( String.valueOf( RESERVED_FOR_EXTENSIONS ) );
|
||||
}
|
||||
|
||||
void recognize( AbstractOptionSpec<?> spec ) {
|
||||
recognizedOptions.putAll( spec.options(), spec );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Writes information about the options this parser recognizes to the given output
|
||||
* sink.</p>
|
||||
*
|
||||
* <p>The output sink is flushed, but not closed.</p>
|
||||
*
|
||||
* @param sink the sink to write information to
|
||||
* @throws IOException if there is a problem writing to the sink
|
||||
* @throws NullPointerException if <var>sink</var> is {@code null}
|
||||
* @see #printHelpOn(Writer)
|
||||
*/
|
||||
public void printHelpOn( OutputStream sink ) throws IOException {
|
||||
printHelpOn( new OutputStreamWriter( sink ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Writes information about the options this parser recognizes to the given output
|
||||
* sink.</p>
|
||||
*
|
||||
* <p>The output sink is flushed, but not closed.</p>
|
||||
*
|
||||
* @param sink the sink to write information to
|
||||
* @throws IOException if there is a problem writing to the sink
|
||||
* @throws NullPointerException if <var>sink</var> is {@code null}
|
||||
* @see #printHelpOn(OutputStream)
|
||||
*/
|
||||
public void printHelpOn( Writer sink ) throws IOException {
|
||||
sink.write( new HelpFormatter().format( recognizedOptions.toJavaUtilMap() ) );
|
||||
sink.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Parses the given command line arguments according to the option specifications
|
||||
* given to the parser.</p>
|
||||
*
|
||||
* @param arguments arguments to parse
|
||||
* @return an {@link OptionSet} describing the parsed options, their arguments, and
|
||||
* any non-option arguments found
|
||||
* @throws OptionException if problems are detected while parsing
|
||||
* @throws NullPointerException if the argument list is {@code null}
|
||||
*/
|
||||
public OptionSet parse( String... arguments ) {
|
||||
ArgumentList argumentList = new ArgumentList( arguments );
|
||||
OptionSet detected = new OptionSet( defaultValues() );
|
||||
|
||||
while ( argumentList.hasMore() )
|
||||
state.handleArgument( this, argumentList, detected );
|
||||
|
||||
reset();
|
||||
return detected;
|
||||
}
|
||||
|
||||
void handleLongOptionToken( String candidate, ArgumentList arguments, OptionSet detected ) {
|
||||
KeyValuePair optionAndArgument = parseLongOptionWithArgument( candidate );
|
||||
|
||||
if ( !isRecognized( optionAndArgument.key ) )
|
||||
throw unrecognizedOption( optionAndArgument.key );
|
||||
|
||||
AbstractOptionSpec<?> optionSpec = specFor( optionAndArgument.key );
|
||||
optionSpec.handleOption( this, arguments, detected, optionAndArgument.value );
|
||||
}
|
||||
|
||||
void handleShortOptionToken( String candidate, ArgumentList arguments, OptionSet detected ) {
|
||||
KeyValuePair optionAndArgument = parseShortOptionWithArgument( candidate );
|
||||
|
||||
if ( isRecognized( optionAndArgument.key ) ) {
|
||||
specFor( optionAndArgument.key ).handleOption( this, arguments, detected, optionAndArgument.value );
|
||||
}
|
||||
else
|
||||
handleShortOptionCluster( candidate, arguments, detected );
|
||||
}
|
||||
|
||||
private void handleShortOptionCluster( String candidate, ArgumentList arguments, OptionSet detected ) {
|
||||
char[] options = extractShortOptionsFrom( candidate );
|
||||
validateOptionCharacters( options );
|
||||
|
||||
AbstractOptionSpec<?> optionSpec = specFor( options[ 0 ] );
|
||||
|
||||
if ( optionSpec.acceptsArguments() && options.length > 1 ) {
|
||||
String detectedArgument = String.valueOf( options, 1, options.length - 1 );
|
||||
optionSpec.handleOption( this, arguments, detected, detectedArgument );
|
||||
}
|
||||
else {
|
||||
for ( char each : options )
|
||||
specFor( each ).handleOption( this, arguments, detected, null );
|
||||
}
|
||||
}
|
||||
|
||||
void noMoreOptions() {
|
||||
state = OptionParserState.noMoreOptions();
|
||||
}
|
||||
|
||||
boolean looksLikeAnOption( String argument ) {
|
||||
return isShortOptionToken( argument ) || isLongOptionToken( argument );
|
||||
}
|
||||
|
||||
private boolean isRecognized( String option ) {
|
||||
return recognizedOptions.contains( option );
|
||||
}
|
||||
|
||||
private AbstractOptionSpec<?> specFor( char option ) {
|
||||
return specFor( String.valueOf( option ) );
|
||||
}
|
||||
|
||||
private AbstractOptionSpec<?> specFor( String option ) {
|
||||
return recognizedOptions.get( option );
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
state = moreOptions( posixlyCorrect );
|
||||
}
|
||||
|
||||
private static char[] extractShortOptionsFrom( String argument ) {
|
||||
char[] options = new char[ argument.length() - 1 ];
|
||||
argument.getChars( 1, argument.length(), options, 0 );
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private void validateOptionCharacters( char[] options ) {
|
||||
for ( int i = 0; i < options.length; ++i ) {
|
||||
String option = String.valueOf( options[ i ] );
|
||||
|
||||
if ( !isRecognized( option ) )
|
||||
throw unrecognizedOption( option );
|
||||
|
||||
if ( specFor( option ).acceptsArguments() ) {
|
||||
if ( i > 0 )
|
||||
throw illegalOptionCluster( option );
|
||||
|
||||
// remainder of chars are the argument to the option at char 0
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static KeyValuePair parseLongOptionWithArgument( String argument ) {
|
||||
return KeyValuePair.valueOf( argument.substring( 2 ) );
|
||||
}
|
||||
|
||||
private static KeyValuePair parseShortOptionWithArgument( String argument ) {
|
||||
return KeyValuePair.valueOf( argument.substring( 1 ) );
|
||||
}
|
||||
|
||||
private Map<String, List<?>> defaultValues() {
|
||||
Map<String, List<?>> defaults = new HashMap<String, List<?>>();
|
||||
for ( Map.Entry<String, AbstractOptionSpec<?>> each : recognizedOptions.toJavaUtilMap().entrySet() )
|
||||
defaults.put( each.getKey(), each.getValue().defaultValues() );
|
||||
return defaults;
|
||||
}
|
||||
}
|
69
src/joptsimple/OptionParserState.java
Normale Datei
69
src/joptsimple/OptionParserState.java
Normale Datei
@ -0,0 +1,69 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import static joptsimple.ParserRules.*;
|
||||
|
||||
/**
|
||||
* <p>Abstraction of parser state; mostly serves to model how a parser behaves depending
|
||||
* on whether end-of-options has been detected.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionParserState.java,v 1.8 2009/09/28 01:12:48 pholser Exp $
|
||||
*/
|
||||
abstract class OptionParserState {
|
||||
static OptionParserState noMoreOptions() {
|
||||
return new OptionParserState() {
|
||||
@Override
|
||||
protected void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
|
||||
detectedOptions.addNonOptionArgument( arguments.next() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static OptionParserState moreOptions( final boolean posixlyCorrect ) {
|
||||
return new OptionParserState() {
|
||||
@Override
|
||||
protected void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
|
||||
String candidate = arguments.next();
|
||||
if ( isOptionTerminator( candidate ) )
|
||||
parser.noMoreOptions();
|
||||
else if ( isLongOptionToken( candidate ) )
|
||||
parser.handleLongOptionToken( candidate, arguments, detectedOptions );
|
||||
else if ( isShortOptionToken( candidate ) )
|
||||
parser.handleShortOptionToken( candidate, arguments, detectedOptions );
|
||||
else {
|
||||
if ( posixlyCorrect )
|
||||
parser.noMoreOptions();
|
||||
|
||||
detectedOptions.addNonOptionArgument( candidate );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions );
|
||||
}
|
301
src/joptsimple/OptionSet.java
Normale Datei
301
src/joptsimple/OptionSet.java
Normale Datei
@ -0,0 +1,301 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import static joptsimple.internal.Objects.*;
|
||||
|
||||
/**
|
||||
* <p>Representation of a group of detected command line options, their arguments, and
|
||||
* non-option arguments.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionSet.java,v 1.26 2009/10/25 18:37:05 pholser Exp $
|
||||
*/
|
||||
public class OptionSet {
|
||||
private final Map<String, AbstractOptionSpec<?>> detectedOptions;
|
||||
private final Map<AbstractOptionSpec<?>, List<String>> optionsToArguments;
|
||||
private final List<String> nonOptionArguments;
|
||||
private final Map<String, List<?>> defaultValues;
|
||||
|
||||
/**
|
||||
* Package-private because clients don't create these.
|
||||
*/
|
||||
OptionSet( Map<String, List<?>> defaults ) {
|
||||
detectedOptions = new HashMap<String, AbstractOptionSpec<?>>();
|
||||
optionsToArguments = new IdentityHashMap<AbstractOptionSpec<?>, List<String>>();
|
||||
nonOptionArguments = new ArrayList<String>();
|
||||
defaultValues = new HashMap<String, List<?>>( defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells whether the given option was detected.</p>
|
||||
*
|
||||
* @param option the option to search for
|
||||
* @return {@code true} if the option was detected
|
||||
* @see #has(OptionSpec)
|
||||
*/
|
||||
public boolean has( String option ) {
|
||||
return detectedOptions.containsKey( option );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells whether the given option was detected.</p>
|
||||
*
|
||||
* <p>This method recognizes only instances of options returned from the fluent
|
||||
* interface methods.</p>
|
||||
*
|
||||
* <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[])} default argument value}
|
||||
* for an option does not cause this method to return {@code true} if the option was not detected on the command
|
||||
* line.</p>
|
||||
*
|
||||
* @param option the option to search for
|
||||
* @return {@code true} if the option was detected
|
||||
* @see #has(String)
|
||||
*/
|
||||
public boolean has( OptionSpec<?> option ) {
|
||||
return optionsToArguments.containsKey( option );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells whether there are any arguments associated with the given option.</p>
|
||||
*
|
||||
* @param option the option to search for
|
||||
* @return {@code true} if the option was detected and at least one argument was
|
||||
* detected for the option
|
||||
* @see #hasArgument(OptionSpec)
|
||||
*/
|
||||
public boolean hasArgument( String option ) {
|
||||
AbstractOptionSpec<?> spec = detectedOptions.get( option );
|
||||
return spec != null && hasArgument( spec );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells whether there are any arguments associated with the given option.</p>
|
||||
*
|
||||
* <p>This method recognizes only instances of options returned from the fluent
|
||||
* interface methods.</p>
|
||||
*
|
||||
* <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
|
||||
* for an option does not cause this method to return {@code true} if the option was not detected on the command
|
||||
* line, or if the option can take an optional argument but did not have one on the command line.</p>
|
||||
*
|
||||
* @param option the option to search for
|
||||
* @return {@code true} if the option was detected and at least one argument was
|
||||
* detected for the option
|
||||
* @throws NullPointerException if {@code option} is {@code null}
|
||||
* @see #hasArgument(String)
|
||||
*/
|
||||
public boolean hasArgument( OptionSpec<?> option ) {
|
||||
ensureNotNull( option );
|
||||
|
||||
List<String> values = optionsToArguments.get( option );
|
||||
return values != null && !values.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gives the argument associated with the given option. If the option was given
|
||||
* an argument type, the argument will take on that type; otherwise, it will be a
|
||||
* {@link String}.</p>
|
||||
*
|
||||
* <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
|
||||
* for an option will cause this method to return that default value even if the option was not detected on the
|
||||
* command line, or if the option can take an optional argument but did not have one on the command line.</p>
|
||||
*
|
||||
* @param option the option to search for
|
||||
* @return the argument of the given option; {@code null} if no argument is
|
||||
* present, or that option was not detected
|
||||
* @throws NullPointerException if {@code option} is {@code null}
|
||||
* @throws OptionException if more than one argument was detected for the option
|
||||
*/
|
||||
public Object valueOf( String option ) {
|
||||
ensureNotNull( option );
|
||||
|
||||
AbstractOptionSpec<?> spec = detectedOptions.get( option );
|
||||
if ( spec == null ) {
|
||||
List<?> defaults = defaultValuesFor( option );
|
||||
return defaults.isEmpty() ? null : defaults.get( 0 );
|
||||
}
|
||||
|
||||
return valueOf( spec );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gives the argument associated with the given option.</p>
|
||||
*
|
||||
* <p>This method recognizes only instances of options returned from the fluent
|
||||
* interface methods.</p>
|
||||
*
|
||||
* @param <V> represents the type of the arguments the given option accepts
|
||||
* @param option the option to search for
|
||||
* @return the argument of the given option; {@code null} if no argument is
|
||||
* present, or that option was not detected
|
||||
* @throws OptionException if more than one argument was detected for the option
|
||||
* @throws NullPointerException if {@code option} is {@code null}
|
||||
* @throws ClassCastException if the arguments of this option are not of the
|
||||
* expected type
|
||||
*/
|
||||
public <V> V valueOf( OptionSpec<V> option ) {
|
||||
ensureNotNull( option );
|
||||
|
||||
List<V> values = valuesOf( option );
|
||||
switch ( values.size() ) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return values.get( 0 );
|
||||
default:
|
||||
throw new MultipleArgumentsForOptionException( option.options() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gives any arguments associated with the given option. If the option was given
|
||||
* an argument type, the arguments will take on that type; otherwise, they will be
|
||||
* {@link String}s.</p>
|
||||
*
|
||||
* @param option the option to search for
|
||||
* @return the arguments associated with the option, as a list of objects of the
|
||||
* type given to the arguments; an empty list if no such arguments are present, or if
|
||||
* the option was not detected
|
||||
* @throws NullPointerException if {@code option} is {@code null}
|
||||
*/
|
||||
public List<?> valuesOf( String option ) {
|
||||
ensureNotNull( option );
|
||||
|
||||
AbstractOptionSpec<?> spec = detectedOptions.get( option );
|
||||
return spec == null ? defaultValuesFor( option ) : valuesOf( spec );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gives any arguments associated with the given option. If the option was given
|
||||
* an argument type, the arguments will take on that type; otherwise, they will be
|
||||
* {@link String}s.</p>
|
||||
*
|
||||
* <p>This method recognizes only instances of options returned from the fluent
|
||||
* interface methods.</p>
|
||||
*
|
||||
* @param <V> represents the type of the arguments the given option accepts
|
||||
* @param option the option to search for
|
||||
* @return the arguments associated with the option; an empty list if no such
|
||||
* arguments are present, or if the option was not detected
|
||||
* @throws NullPointerException if {@code option} is {@code null}
|
||||
* @throws OptionException if there is a problem converting the option's arguments to
|
||||
* the desired type; for example, if the type does not implement a correct conversion
|
||||
* constructor or method
|
||||
*/
|
||||
public <V> List<V> valuesOf( OptionSpec<V> option ) {
|
||||
ensureNotNull( option );
|
||||
|
||||
List<String> values = optionsToArguments.get( option );
|
||||
if ( values == null || values.isEmpty() )
|
||||
return defaultValueFor( option );
|
||||
|
||||
AbstractOptionSpec<V> spec = (AbstractOptionSpec<V>) option;
|
||||
List<V> convertedValues = new ArrayList<V>();
|
||||
for ( String each : values )
|
||||
convertedValues.add( spec.convert( each ) );
|
||||
|
||||
return unmodifiableList( convertedValues );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the detected non-option arguments
|
||||
*/
|
||||
public List<String> nonOptionArguments() {
|
||||
return unmodifiableList( nonOptionArguments );
|
||||
}
|
||||
|
||||
void add( AbstractOptionSpec<?> option ) {
|
||||
addWithArgument( option, null );
|
||||
}
|
||||
|
||||
void addWithArgument( AbstractOptionSpec<?> option, String argument ) {
|
||||
for ( String each : option.options() )
|
||||
detectedOptions.put( each, option );
|
||||
|
||||
List<String> optionArguments = optionsToArguments.get( option );
|
||||
|
||||
if ( optionArguments == null ) {
|
||||
optionArguments = new ArrayList<String>();
|
||||
optionsToArguments.put( option, optionArguments );
|
||||
}
|
||||
|
||||
if ( argument != null )
|
||||
optionArguments.add( argument );
|
||||
}
|
||||
|
||||
void addNonOptionArgument( String argument ) {
|
||||
nonOptionArguments.add( argument );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object that ) {
|
||||
if ( this == that )
|
||||
return true;
|
||||
|
||||
if ( that == null || !getClass().equals( that.getClass() ) )
|
||||
return false;
|
||||
|
||||
OptionSet other = (OptionSet) that;
|
||||
Map<AbstractOptionSpec<?>, List<String>> thisOptionsToArguments =
|
||||
new HashMap<AbstractOptionSpec<?>, List<String>>( optionsToArguments );
|
||||
Map<AbstractOptionSpec<?>, List<String>> otherOptionsToArguments =
|
||||
new HashMap<AbstractOptionSpec<?>, List<String>>( other.optionsToArguments );
|
||||
return detectedOptions.equals( other.detectedOptions )
|
||||
&& thisOptionsToArguments.equals( otherOptionsToArguments )
|
||||
&& nonOptionArguments.equals( other.nonOptionArguments() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Map<AbstractOptionSpec<?>, List<String>> thisOptionsToArguments =
|
||||
new HashMap<AbstractOptionSpec<?>, List<String>>( optionsToArguments );
|
||||
return detectedOptions.hashCode()
|
||||
^ thisOptionsToArguments.hashCode()
|
||||
^ nonOptionArguments.hashCode();
|
||||
}
|
||||
|
||||
private <V> List<V> defaultValuesFor( String option ) {
|
||||
if ( defaultValues.containsKey( option ) ) {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
List<V> defaults = (List<V>) defaultValues.get( option );
|
||||
return defaults;
|
||||
}
|
||||
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
private <V> List<V> defaultValueFor( OptionSpec<V> option ) {
|
||||
return defaultValuesFor( option.options().iterator().next() );
|
||||
}
|
||||
}
|
95
src/joptsimple/OptionSpec.java
Normale Datei
95
src/joptsimple/OptionSpec.java
Normale Datei
@ -0,0 +1,95 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>Describes options that an option parser recognizes.</p>
|
||||
*
|
||||
* <p>Instances of this interface are returned by the "fluent interface" methods to allow
|
||||
* retrieval of option arguments in a type-safe manner. Here's an example:</p>
|
||||
* <pre><code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* <strong>OptionSpec<Integer></strong> count =
|
||||
* parser.accepts( "count" ).withRequiredArg().ofType( Integer.class );
|
||||
* OptionSet options = parser.parse( "--count", "2" );
|
||||
* assert options.has( count );
|
||||
* int countValue = options.valueOf( count );
|
||||
* assert countValue == count.value( options );
|
||||
* List<Integer> countValues = options.valuesOf( count );
|
||||
* assert countValues.equals( count.values( options ) );
|
||||
* </code></pre>
|
||||
*
|
||||
* @param <V> represents the type of the arguments this option accepts
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionSpec.java,v 1.25 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
public interface OptionSpec<V> {
|
||||
/**
|
||||
* <p>Gives any arguments associated with the given option in the given set of
|
||||
* detected options.</p>
|
||||
*
|
||||
* <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
|
||||
* for this option will cause this method to return that default value even if this option was not detected on the
|
||||
* command line, or if this option can take an optional argument but did not have one on the command line.</p>
|
||||
*
|
||||
* @param detectedOptions the detected options to search in
|
||||
* @return the arguments associated with this option; an empty list if no such
|
||||
* arguments are present, or if this option was not detected
|
||||
* @throws OptionException if there is a problem converting this option's arguments
|
||||
* to the desired type; for example, if the type does not implement a correct
|
||||
* conversion constructor or method
|
||||
* @throws NullPointerException if {@code detectedOptions} is {@code null}
|
||||
* @see OptionSet#valuesOf(OptionSpec)
|
||||
*/
|
||||
List<V> values( OptionSet detectedOptions );
|
||||
|
||||
/**
|
||||
* <p>Gives the argument associated with the given option in the given set of
|
||||
* detected options.</p>
|
||||
*
|
||||
* <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
|
||||
* for this option will cause this method to return that default value even if this option was not detected on the
|
||||
* command line, or if this option can take an optional argument but did not have one on the command line.</p>
|
||||
*
|
||||
* @param detectedOptions the detected options to search in
|
||||
* @return the argument of the this option; {@code null} if no argument is present,
|
||||
* or that option was not detected
|
||||
* @throws OptionException if more than one argument was detected for the option
|
||||
* @throws NullPointerException if {@code detectedOptions} is {@code null}
|
||||
* @throws ClassCastException if the arguments of this option are not of the
|
||||
* expected type
|
||||
* @see OptionSet#valueOf(OptionSpec)
|
||||
*/
|
||||
V value( OptionSet detectedOptions );
|
||||
|
||||
/**
|
||||
* @return the string representations of this option
|
||||
*/
|
||||
Collection<String> options();
|
||||
}
|
101
src/joptsimple/OptionSpecBuilder.java
Normale Datei
101
src/joptsimple/OptionSpecBuilder.java
Normale Datei
@ -0,0 +1,101 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>Allows callers to specify whether a given option accepts arguments (required or
|
||||
* optional).</p>
|
||||
*
|
||||
* <p>Instances are returned from {@link OptionParser#accepts(String)} to allow the
|
||||
* formation of parser directives as sentences in a "fluent interface" language. For
|
||||
* example:</p>
|
||||
*
|
||||
* <pre><code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* parser.accepts( "c" ).<strong>withRequiredArg()</strong>.ofType( Integer.class );
|
||||
* </code></pre>
|
||||
*
|
||||
* <p>If no methods are invoked on an instance of this class, then that instance's option
|
||||
* will accept no argument.</p>
|
||||
*
|
||||
* <p>Note that you should not use the fluent interface clauses in a way that would
|
||||
* defeat the typing of option arguments:</p>
|
||||
*
|
||||
* <pre><code>
|
||||
* OptionParser parser = new OptionParser();
|
||||
* ArgumentAcceptingOptionSpec<String> optionC =
|
||||
* parser.accepts( "c" ).withRequiredArg();
|
||||
* <strong>optionC.ofType( Integer.class ); // DON'T THROW AWAY THE TYPE!</strong>
|
||||
*
|
||||
* String value = parser.parse( "-c", "2" ).valueOf( optionC ); // ClassCastException
|
||||
* </code></pre>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionSpecBuilder.java,v 1.19 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
public class OptionSpecBuilder extends NoArgumentOptionSpec {
|
||||
private final OptionParser parser;
|
||||
|
||||
OptionSpecBuilder( OptionParser parser, Collection<String> options, String description ) {
|
||||
super( options, description );
|
||||
|
||||
this.parser = parser;
|
||||
attachToParser();
|
||||
}
|
||||
|
||||
private void attachToParser() {
|
||||
parser.recognize( this );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Informs an option parser that this builder's option requires an argument.</p>
|
||||
*
|
||||
* @return a specification for the option
|
||||
*/
|
||||
public ArgumentAcceptingOptionSpec<String> withRequiredArg() {
|
||||
ArgumentAcceptingOptionSpec<String> newSpec =
|
||||
new RequiredArgumentOptionSpec<String>( options(), description() );
|
||||
parser.recognize( newSpec );
|
||||
|
||||
return newSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Informs an option parser that this builder's option accepts an optional
|
||||
* argument.</p>
|
||||
*
|
||||
* @return a specification for the option
|
||||
*/
|
||||
public ArgumentAcceptingOptionSpec<String> withOptionalArg() {
|
||||
ArgumentAcceptingOptionSpec<String> newSpec =
|
||||
new OptionalArgumentOptionSpec<String>( options(), description() );
|
||||
parser.recognize( newSpec );
|
||||
|
||||
return newSpec;
|
||||
}
|
||||
}
|
119
src/joptsimple/OptionSpecTokenizer.java
Normale Datei
119
src/joptsimple/OptionSpecTokenizer.java
Normale Datei
@ -0,0 +1,119 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static joptsimple.ParserRules.*;
|
||||
|
||||
/**
|
||||
* <p>Tokenizes a short option specification string.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionSpecTokenizer.java,v 1.14 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class OptionSpecTokenizer {
|
||||
private static final char POSIXLY_CORRECT_MARKER = '+';
|
||||
|
||||
private String specification;
|
||||
private int index;
|
||||
|
||||
OptionSpecTokenizer( String specification ) {
|
||||
if ( specification == null )
|
||||
throw new NullPointerException( "null option specification" );
|
||||
|
||||
this.specification = specification;
|
||||
}
|
||||
|
||||
boolean hasMore() {
|
||||
return index < specification.length();
|
||||
}
|
||||
|
||||
AbstractOptionSpec<?> next() {
|
||||
if ( !hasMore() )
|
||||
throw new NoSuchElementException();
|
||||
|
||||
|
||||
String optionCandidate = String.valueOf( specification.charAt( index ) );
|
||||
index++;
|
||||
|
||||
AbstractOptionSpec<?> spec;
|
||||
if ( RESERVED_FOR_EXTENSIONS.equals( optionCandidate ) ) {
|
||||
spec = handleReservedForExtensionsToken();
|
||||
|
||||
if ( spec != null )
|
||||
return spec;
|
||||
}
|
||||
|
||||
ensureLegalOption( optionCandidate );
|
||||
|
||||
if ( hasMore() )
|
||||
spec = specification.charAt( index ) == ':'
|
||||
? handleArgumentAcceptingOption( optionCandidate )
|
||||
: new NoArgumentOptionSpec( optionCandidate );
|
||||
else
|
||||
spec = new NoArgumentOptionSpec( optionCandidate );
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
void configure( OptionParser parser ) {
|
||||
adjustForPosixlyCorrect( parser );
|
||||
|
||||
while ( hasMore() )
|
||||
parser.recognize( next() );
|
||||
}
|
||||
|
||||
private void adjustForPosixlyCorrect( OptionParser parser ) {
|
||||
if ( POSIXLY_CORRECT_MARKER == specification.charAt( 0 ) ) {
|
||||
parser.posixlyCorrect( true );
|
||||
specification = specification.substring( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
private AbstractOptionSpec<?> handleReservedForExtensionsToken() {
|
||||
if ( !hasMore() )
|
||||
return new NoArgumentOptionSpec( RESERVED_FOR_EXTENSIONS );
|
||||
|
||||
if ( specification.charAt( index ) == ';' ) {
|
||||
++index;
|
||||
return new AlternativeLongOptionSpec();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private AbstractOptionSpec<?> handleArgumentAcceptingOption( String candidate ) {
|
||||
index++;
|
||||
|
||||
if ( hasMore() && specification.charAt( index ) == ':' ) {
|
||||
index++;
|
||||
return new OptionalArgumentOptionSpec<String>( candidate );
|
||||
}
|
||||
|
||||
return new RequiredArgumentOptionSpec<String>( candidate );
|
||||
}
|
||||
}
|
42
src/joptsimple/OptionSpecVisitor.java
Normale Datei
42
src/joptsimple/OptionSpecVisitor.java
Normale Datei
@ -0,0 +1,42 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
/**
|
||||
* <p>Visitor interface for option specifications.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionSpecVisitor.java,v 1.6 2009/08/13 00:34:35 pholser Exp $
|
||||
*/
|
||||
interface OptionSpecVisitor {
|
||||
void visit( NoArgumentOptionSpec spec );
|
||||
|
||||
void visit( RequiredArgumentOptionSpec<?> spec );
|
||||
|
||||
void visit( OptionalArgumentOptionSpec<?> spec );
|
||||
|
||||
void visit( AlternativeLongOptionSpec spec );
|
||||
}
|
75
src/joptsimple/OptionalArgumentOptionSpec.java
Normale Datei
75
src/joptsimple/OptionalArgumentOptionSpec.java
Normale Datei
@ -0,0 +1,75 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>Specification of an option that accepts an optional argument.</p>
|
||||
*
|
||||
* @param <V> represents the type of the arguments this option accepts
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: OptionalArgumentOptionSpec.java,v 1.17 2009/09/28 01:12:48 pholser Exp $
|
||||
*/
|
||||
class OptionalArgumentOptionSpec<V> extends ArgumentAcceptingOptionSpec<V> {
|
||||
OptionalArgumentOptionSpec( String option ) {
|
||||
super( option, false );
|
||||
}
|
||||
|
||||
OptionalArgumentOptionSpec( Collection<String> options, String description ) {
|
||||
super( options, false, description );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
|
||||
if ( arguments.hasMore() ) {
|
||||
String nextArgument = arguments.peek();
|
||||
|
||||
if ( !parser.looksLikeAnOption( nextArgument ) )
|
||||
handleOptionArgument( parser, detectedOptions, arguments );
|
||||
else if ( isArgumentOfNumberType() && canConvertArgument( nextArgument ) )
|
||||
addArguments( detectedOptions, arguments.next() );
|
||||
else
|
||||
detectedOptions.add( this );
|
||||
}
|
||||
else
|
||||
detectedOptions.add( this );
|
||||
}
|
||||
|
||||
private void handleOptionArgument( OptionParser parser, OptionSet detectedOptions, ArgumentList arguments ) {
|
||||
if ( parser.posixlyCorrect() ) {
|
||||
detectedOptions.add( this );
|
||||
parser.noMoreOptions();
|
||||
}
|
||||
else
|
||||
addArguments( detectedOptions, arguments.next() );
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept( OptionSpecVisitor visitor ) {
|
||||
visitor.visit( this );
|
||||
}
|
||||
}
|
88
src/joptsimple/ParserRules.java
Normale Datei
88
src/joptsimple/ParserRules.java
Normale Datei
@ -0,0 +1,88 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
import static java.lang.Character.*;
|
||||
|
||||
/**
|
||||
* <p>Can tell whether or not options are well-formed.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ParserRules.java,v 1.14 2009/09/23 00:39:14 pholser Exp $
|
||||
*/
|
||||
final class ParserRules {
|
||||
static final char HYPHEN_CHAR = '-';
|
||||
static final String HYPHEN = String.valueOf( HYPHEN_CHAR );
|
||||
static final String DOUBLE_HYPHEN = "--";
|
||||
static final String OPTION_TERMINATOR = DOUBLE_HYPHEN;
|
||||
static final String RESERVED_FOR_EXTENSIONS = "W";
|
||||
|
||||
static {
|
||||
new ParserRules();
|
||||
}
|
||||
|
||||
private ParserRules() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
static boolean isShortOptionToken( String argument ) {
|
||||
return argument.startsWith( HYPHEN )
|
||||
&& !HYPHEN.equals( argument )
|
||||
&& !isLongOptionToken( argument );
|
||||
}
|
||||
|
||||
static boolean isLongOptionToken( String argument ) {
|
||||
return argument.startsWith( DOUBLE_HYPHEN ) && !isOptionTerminator( argument );
|
||||
}
|
||||
|
||||
static boolean isOptionTerminator( String argument ) {
|
||||
return OPTION_TERMINATOR.equals( argument );
|
||||
}
|
||||
|
||||
static void ensureLegalOption( String option ) {
|
||||
if ( option.startsWith( HYPHEN ) )
|
||||
throw new IllegalOptionSpecificationException( String.valueOf( option ) );
|
||||
|
||||
for ( int i = 0; i < option.length(); ++i )
|
||||
ensureLegalOptionCharacter( option.charAt( i ) );
|
||||
}
|
||||
|
||||
static void ensureLegalOptions( Collection<String> options ) {
|
||||
for ( String each : options )
|
||||
ensureLegalOption( each );
|
||||
}
|
||||
|
||||
private static void ensureLegalOptionCharacter( char option ) {
|
||||
if ( !( isLetterOrDigit( option ) || isAllowedPunctuation( option ) ) )
|
||||
throw new IllegalOptionSpecificationException( String.valueOf( option ) );
|
||||
}
|
||||
|
||||
private static boolean isAllowedPunctuation( char option ) {
|
||||
String allowedPunctuation = "?." + HYPHEN_CHAR;
|
||||
return allowedPunctuation.indexOf( option ) != -1;
|
||||
}
|
||||
}
|
58
src/joptsimple/RequiredArgumentOptionSpec.java
Normale Datei
58
src/joptsimple/RequiredArgumentOptionSpec.java
Normale Datei
@ -0,0 +1,58 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>Specification of an option that accepts a required argument.</p>
|
||||
*
|
||||
* @param <V> represents the type of the arguments this option accepts
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: RequiredArgumentOptionSpec.java,v 1.16 2009/09/28 01:12:48 pholser Exp $
|
||||
*/
|
||||
class RequiredArgumentOptionSpec<V> extends ArgumentAcceptingOptionSpec<V> {
|
||||
RequiredArgumentOptionSpec( String option ) {
|
||||
super( option, true );
|
||||
}
|
||||
|
||||
RequiredArgumentOptionSpec( Collection<String> options, String description ) {
|
||||
super( options, true, description );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
|
||||
if ( !arguments.hasMore() )
|
||||
throw new OptionMissingRequiredArgumentException( options() );
|
||||
|
||||
addArguments( detectedOptions, arguments.next() );
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept( OptionSpecVisitor visitor ) {
|
||||
visitor.visit( this );
|
||||
}
|
||||
}
|
47
src/joptsimple/UnrecognizedOptionException.java
Normale Datei
47
src/joptsimple/UnrecognizedOptionException.java
Normale Datei
@ -0,0 +1,47 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
/**
|
||||
* <p>Thrown when the option parser encounters an unrecognized option.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: UnrecognizedOptionException.java,v 1.10 2009/10/25 18:37:06 pholser Exp $
|
||||
*/
|
||||
class UnrecognizedOptionException extends OptionException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
UnrecognizedOptionException( String option ) {
|
||||
super( singletonList( option ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return singleOptionMessage() + " is not a recognized option";
|
||||
}
|
||||
}
|
56
src/joptsimple/ValueConversionException.java
Normale Datei
56
src/joptsimple/ValueConversionException.java
Normale Datei
@ -0,0 +1,56 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
/**
|
||||
* Thrown by {@link ValueConverter}s when problems occur in converting string values to
|
||||
* other Java types.
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ValueConversionException.java,v 1.5 2009/08/13 00:34:35 pholser Exp $
|
||||
*/
|
||||
public class ValueConversionException extends RuntimeException {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
/**
|
||||
* Creates a new exception with the specified detail message.
|
||||
*
|
||||
* @param message the detail message
|
||||
*/
|
||||
public ValueConversionException( String message ) {
|
||||
this( message, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new exception with the specified detail message and cause.
|
||||
*
|
||||
* @param message the detail message
|
||||
* @param cause the original exception
|
||||
*/
|
||||
public ValueConversionException( String message, Throwable cause ) {
|
||||
super( message, cause );
|
||||
}
|
||||
}
|
61
src/joptsimple/ValueConverter.java
Normale Datei
61
src/joptsimple/ValueConverter.java
Normale Datei
@ -0,0 +1,61 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple;
|
||||
|
||||
/**
|
||||
* Instances of this interface are used to convert arguments of options into specific
|
||||
* Java types.
|
||||
*
|
||||
* @param <V> constraint on the type of values being converted to
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ValueConverter.java,v 1.9 2009/08/13 00:34:35 pholser Exp $
|
||||
*/
|
||||
public interface ValueConverter<V> {
|
||||
/**
|
||||
* Converts the given string value into a Java type.
|
||||
*
|
||||
* @param value the string to convert
|
||||
* @return the converted value
|
||||
* @throws ValueConversionException if a problem occurs while converting the value
|
||||
*/
|
||||
V convert( String value );
|
||||
|
||||
/**
|
||||
* Gives the class of the type of values this converter converts to.
|
||||
*
|
||||
* @return the target class for conversion
|
||||
*/
|
||||
Class<V> valueType();
|
||||
|
||||
/**
|
||||
* Gives a string that describes the pattern of the values this converter expects,
|
||||
* if any. For example, a date converter can respond with a
|
||||
* {@link java.text.SimpleDateFormat date format string}.
|
||||
*
|
||||
* @return a value pattern, or {@code null} if there's nothing interesting here
|
||||
*/
|
||||
String valuePattern();
|
||||
}
|
239
src/joptsimple/internal/AbbreviationMap.java
Normale Datei
239
src/joptsimple/internal/AbbreviationMap.java
Normale Datei
@ -0,0 +1,239 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* <p>A map whose keys are strings; when a key/value pair is added to the map,
|
||||
* the longest unique abbreviations of that key are added as well, and associated with
|
||||
* the value. Thus:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* abbreviations.put( "good", "bye" );
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* <p>would make it such that you could retrieve the value {@code "bye"} from the map
|
||||
* using the keys {@code "good"}, {@code "goo"}, {@code "go"}, and {@code "g"}.
|
||||
* A subsequent invocation of:</p>
|
||||
* <pre>
|
||||
* <code>
|
||||
* abbreviations.put( "go", "fish" );
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* <p>would make it such that you could retrieve the value {@code "bye"} using the keys
|
||||
* {@code "good"} and {@code "goo"}, and the value {@code "fish"} using the key
|
||||
* {@code "go"}. The key {@code "g"} would yield {@code null}, since it would no longer
|
||||
* be a unique abbreviation.</p>
|
||||
*
|
||||
* <p>The data structure is much like a "trie".</p>
|
||||
*
|
||||
* @param <V> a constraint on the types of the values in the map
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: AbbreviationMap.java,v 1.14 2009/10/25 18:37:08 pholser Exp $
|
||||
* @see <a href="http://www.perldoc.com/perl5.8.0/lib/Text/Abbrev.html"> Perl's
|
||||
* Text::Abbrev module</a>
|
||||
*/
|
||||
public class AbbreviationMap<V> {
|
||||
private String key;
|
||||
private V value;
|
||||
private final Map<Character, AbbreviationMap<V>> children = new TreeMap<Character, AbbreviationMap<V>>();
|
||||
private int keysBeyond;
|
||||
|
||||
/**
|
||||
* <p>Tells whether the given key is in the map, or whether the given key is a unique
|
||||
* abbreviation of a key that is in the map.</p>
|
||||
*
|
||||
* @param aKey key to look up
|
||||
* @return {@code true} if {@code key} is present in the map
|
||||
* @throws NullPointerException if {@code key} is {@code null}
|
||||
*/
|
||||
public boolean contains( String aKey ) {
|
||||
return get( aKey ) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Answers the value associated with the given key. The key can be a unique
|
||||
* abbreviation of a key that is in the map. </p>
|
||||
*
|
||||
* @param aKey key to look up
|
||||
* @return the value associated with {@code aKey}; or {@code null} if there is no
|
||||
* such value or {@code aKey} is not a unique abbreviation of a key in the map
|
||||
* @throws NullPointerException if {@code aKey} is {@code null}
|
||||
*/
|
||||
public V get( String aKey ) {
|
||||
char[] chars = charsOf( aKey );
|
||||
|
||||
AbbreviationMap<V> child = this;
|
||||
for ( char each : chars ) {
|
||||
child = child.children.get( each );
|
||||
if ( child == null )
|
||||
return null;
|
||||
}
|
||||
|
||||
return child.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Associates a given value with a given key. If there was a previous
|
||||
* association, the old value is replaced with the new one.</p>
|
||||
*
|
||||
* @param aKey key to create in the map
|
||||
* @param newValue value to associate with the key
|
||||
* @throws NullPointerException if {@code aKey} or {@code newValue} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code aKey} is a zero-length string
|
||||
*/
|
||||
public void put( String aKey, V newValue ) {
|
||||
if ( newValue == null )
|
||||
throw new NullPointerException();
|
||||
if ( aKey.length() == 0 )
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
char[] chars = charsOf( aKey );
|
||||
add( chars, newValue, 0, chars.length );
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Associates a given value with a given set of keys. If there was a previous
|
||||
* association, the old value is replaced with the new one.</p>
|
||||
*
|
||||
* @param keys keys to create in the map
|
||||
* @param newValue value to associate with the key
|
||||
* @throws NullPointerException if {@code keys} or {@code newValue} is {@code null}
|
||||
* @throws IllegalArgumentException if any of {@code keys} is a zero-length string
|
||||
*/
|
||||
public void putAll( Iterable<String> keys, V newValue ) {
|
||||
for ( String each : keys )
|
||||
put( each, newValue );
|
||||
}
|
||||
|
||||
private boolean add( char[] chars, V newValue, int offset, int length ) {
|
||||
if ( offset == length ) {
|
||||
value = newValue;
|
||||
boolean wasAlreadyAKey = key != null;
|
||||
key = new String( chars );
|
||||
return !wasAlreadyAKey;
|
||||
}
|
||||
|
||||
char nextChar = chars[ offset ];
|
||||
AbbreviationMap<V> child = children.get( nextChar );
|
||||
if ( child == null ) {
|
||||
child = new AbbreviationMap<V>();
|
||||
children.put( nextChar, child );
|
||||
}
|
||||
|
||||
boolean newKeyAdded = child.add( chars, newValue, offset + 1, length );
|
||||
|
||||
if ( newKeyAdded )
|
||||
++keysBeyond;
|
||||
|
||||
if ( key == null )
|
||||
value = keysBeyond > 1 ? null : newValue;
|
||||
|
||||
return newKeyAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>If the map contains the given key, dissociates the key from its value.</p>
|
||||
*
|
||||
* @param aKey key to remove
|
||||
* @throws NullPointerException if {@code aKey} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code aKey} is a zero-length string
|
||||
*/
|
||||
public void remove( String aKey ) {
|
||||
if ( aKey.length() == 0 )
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
char[] keyChars = charsOf( aKey );
|
||||
remove( keyChars, 0, keyChars.length );
|
||||
}
|
||||
|
||||
private boolean remove( char[] aKey, int offset, int length ) {
|
||||
if ( offset == length )
|
||||
return removeAtEndOfKey();
|
||||
|
||||
char nextChar = aKey[ offset ];
|
||||
AbbreviationMap<V> child = children.get( nextChar );
|
||||
if ( child == null || !child.remove( aKey, offset + 1, length ) )
|
||||
return false;
|
||||
|
||||
--keysBeyond;
|
||||
if ( child.keysBeyond == 0 )
|
||||
children.remove( nextChar );
|
||||
if ( keysBeyond == 1 && key == null )
|
||||
setValueToThatOfOnlyChild();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setValueToThatOfOnlyChild() {
|
||||
Map.Entry<Character, AbbreviationMap<V>> entry = children.entrySet().iterator().next();
|
||||
AbbreviationMap<V> onlyChild = entry.getValue();
|
||||
value = onlyChild.value;
|
||||
}
|
||||
|
||||
private boolean removeAtEndOfKey() {
|
||||
if ( key == null )
|
||||
return false;
|
||||
|
||||
key = null;
|
||||
if ( keysBeyond == 1 )
|
||||
setValueToThatOfOnlyChild();
|
||||
else
|
||||
value = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a Java map representation of this abbreviation map.
|
||||
*
|
||||
* @return a Java map corresponding to this abbreviation map
|
||||
*/
|
||||
public Map<String, V> toJavaUtilMap() {
|
||||
Map<String, V> mappings = new TreeMap<String, V>();
|
||||
addToMappings( mappings );
|
||||
return mappings;
|
||||
}
|
||||
|
||||
private void addToMappings( Map<String, V> mappings ) {
|
||||
if ( key != null )
|
||||
mappings.put( key, value );
|
||||
|
||||
for ( AbbreviationMap<V> each : children.values() )
|
||||
each.addToMappings( mappings );
|
||||
}
|
||||
|
||||
private static char[] charsOf( String aKey ) {
|
||||
char[] chars = new char[ aKey.length() ];
|
||||
aKey.getChars( 0, aKey.length(), chars, 0 );
|
||||
return chars;
|
||||
}
|
||||
}
|
51
src/joptsimple/internal/Classes.java
Normale Datei
51
src/joptsimple/internal/Classes.java
Normale Datei
@ -0,0 +1,51 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: Classes.java,v 1.10 2009/08/13 01:05:35 pholser Exp $
|
||||
*/
|
||||
public final class Classes {
|
||||
static {
|
||||
new Classes();
|
||||
}
|
||||
|
||||
private Classes() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the "short version" of the given class name. Somewhat naive to inner
|
||||
* classes.
|
||||
*
|
||||
* @param className class name to chew on
|
||||
* @return the short name of the class
|
||||
*/
|
||||
public static String shortNameOf( String className ) {
|
||||
return className.substring( className.lastIndexOf( '.' ) + 1 );
|
||||
}
|
||||
}
|
132
src/joptsimple/internal/Column.java
Normale Datei
132
src/joptsimple/internal/Column.java
Normale Datei
@ -0,0 +1,132 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.text.BreakIterator;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import static java.lang.System.*;
|
||||
import static java.text.BreakIterator.*;
|
||||
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: Column.java,v 1.16 2009/10/25 18:37:08 pholser Exp $
|
||||
*/
|
||||
public class Column {
|
||||
static final Comparator<Column> BY_HEIGHT = new Comparator<Column>() {
|
||||
public int compare( Column first, Column second ) {
|
||||
if ( first.height() < second.height() )
|
||||
return -1;
|
||||
return first.height() == second.height() ? 0 : 1;
|
||||
}
|
||||
};
|
||||
|
||||
private final String header;
|
||||
private final List<String> data;
|
||||
private final int width;
|
||||
private int height;
|
||||
|
||||
Column( String header, int width ) {
|
||||
this.header = header;
|
||||
this.width = Math.max( width, header.length() );
|
||||
data = new LinkedList<String>();
|
||||
height = 0;
|
||||
}
|
||||
|
||||
int addCells( Object cellCandidate ) {
|
||||
int originalHeight = height;
|
||||
|
||||
String source = String.valueOf( cellCandidate ).trim();
|
||||
for ( String eachPiece : source.split( getProperty( "line.separator" ) ) )
|
||||
processNextEmbeddedLine( eachPiece );
|
||||
|
||||
return height - originalHeight;
|
||||
}
|
||||
|
||||
private void processNextEmbeddedLine( String line ) {
|
||||
BreakIterator words = BreakIterator.getLineInstance( Locale.US );
|
||||
words.setText( line );
|
||||
|
||||
StringBuilder nextCell = new StringBuilder();
|
||||
|
||||
int start = words.first();
|
||||
for ( int end = words.next(); end != DONE; start = end, end = words.next() )
|
||||
nextCell = processNextWord( line, nextCell, start, end );
|
||||
|
||||
if ( nextCell.length() > 0 )
|
||||
addCell( nextCell.toString() );
|
||||
}
|
||||
|
||||
private StringBuilder processNextWord( String source, StringBuilder nextCell, int start, int end ) {
|
||||
StringBuilder augmented = nextCell;
|
||||
|
||||
String word = source.substring( start, end );
|
||||
if ( augmented.length() + word.length() > width ) {
|
||||
addCell( augmented.toString() );
|
||||
augmented = new StringBuilder( " " ).append( word );
|
||||
}
|
||||
else
|
||||
augmented.append( word );
|
||||
|
||||
return augmented;
|
||||
}
|
||||
|
||||
void addCell( String newCell ) {
|
||||
data.add( newCell );
|
||||
++height;
|
||||
}
|
||||
|
||||
void writeHeaderOn( StringBuilder buffer, boolean appendSpace ) {
|
||||
buffer.append( header ).append( repeat( ' ', width - header.length() ) );
|
||||
|
||||
if ( appendSpace )
|
||||
buffer.append( ' ' );
|
||||
}
|
||||
|
||||
void writeSeparatorOn( StringBuilder buffer, boolean appendSpace ) {
|
||||
buffer.append( repeat( '-', header.length() ) ).append( repeat( ' ', width - header.length() ) );
|
||||
if ( appendSpace )
|
||||
buffer.append( ' ' );
|
||||
}
|
||||
|
||||
void writeCellOn( int index, StringBuilder buffer, boolean appendSpace ) {
|
||||
if ( index < data.size() ) {
|
||||
String item = data.get( index );
|
||||
|
||||
buffer.append( item ).append( repeat( ' ', width - item.length() ) );
|
||||
if ( appendSpace )
|
||||
buffer.append( ' ' );
|
||||
}
|
||||
}
|
||||
|
||||
int height() {
|
||||
return height;
|
||||
}
|
||||
}
|
42
src/joptsimple/internal/ColumnWidthCalculator.java
Normale Datei
42
src/joptsimple/internal/ColumnWidthCalculator.java
Normale Datei
@ -0,0 +1,42 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ColumnWidthCalculator.java,v 1.4 2009/08/13 00:34:36 pholser Exp $
|
||||
*/
|
||||
class ColumnWidthCalculator {
|
||||
int calculate( int totalWidth, int numberOfColumns ) {
|
||||
if ( numberOfColumns == 1 )
|
||||
return totalWidth;
|
||||
|
||||
int remainder = totalWidth % numberOfColumns;
|
||||
if ( remainder == numberOfColumns - 1 )
|
||||
return totalWidth / numberOfColumns;
|
||||
return totalWidth / numberOfColumns - 1;
|
||||
}
|
||||
}
|
162
src/joptsimple/internal/ColumnarData.java
Normale Datei
162
src/joptsimple/internal/ColumnarData.java
Normale Datei
@ -0,0 +1,162 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import static java.lang.Integer.*;
|
||||
import static java.lang.System.*;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import static joptsimple.internal.Column.*;
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* <p>A means to display data in a text grid.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ColumnarData.java,v 1.17 2009/10/25 18:37:08 pholser Exp $
|
||||
*/
|
||||
public class ColumnarData {
|
||||
private static final String LINE_SEPARATOR = getProperty( "line.separator" );
|
||||
private static final int TOTAL_WIDTH = 80;
|
||||
|
||||
private final ColumnWidthCalculator widthCalculator;
|
||||
private final List<Column> columns;
|
||||
private final String[] headers;
|
||||
|
||||
/**
|
||||
* Creates a new grid with the given column headers.
|
||||
*
|
||||
* @param headers column headers
|
||||
*/
|
||||
public ColumnarData( String... headers ) {
|
||||
this.headers = headers.clone();
|
||||
widthCalculator = new ColumnWidthCalculator();
|
||||
columns = new LinkedList<Column>();
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a row to the grid. The data will fall under the corresponding headers.
|
||||
* There can be fewer elements in the row than headers. Any data in columns outside
|
||||
* of the number of headers will not be added to the grid.
|
||||
*
|
||||
* @param rowData row data to add
|
||||
*/
|
||||
public void addRow( Object... rowData ) {
|
||||
int[] numberOfCellsAddedAt = addRowCells( rowData );
|
||||
addPaddingCells( numberOfCellsAddedAt );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a string that represents the data formatted in columns.
|
||||
*
|
||||
* @return the formatted grid
|
||||
*/
|
||||
public String format() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
writeHeadersOn( buffer );
|
||||
writeSeparatorsOn( buffer );
|
||||
writeRowsOn( buffer );
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all data from the grid, but preserves the headers.
|
||||
*/
|
||||
public final void clear() {
|
||||
columns.clear();
|
||||
|
||||
int desiredColumnWidth = widthCalculator.calculate( TOTAL_WIDTH, headers.length );
|
||||
for ( String each : headers )
|
||||
columns.add( new Column( each, desiredColumnWidth ) );
|
||||
}
|
||||
|
||||
private void writeHeadersOn( StringBuilder buffer ) {
|
||||
for ( Iterator<Column> iter = columns.iterator(); iter.hasNext(); )
|
||||
iter.next().writeHeaderOn( buffer, iter.hasNext() );
|
||||
|
||||
buffer.append( LINE_SEPARATOR );
|
||||
}
|
||||
|
||||
private void writeSeparatorsOn( StringBuilder buffer ) {
|
||||
for ( Iterator<Column> iter = columns.iterator(); iter.hasNext(); )
|
||||
iter.next().writeSeparatorOn( buffer, iter.hasNext() );
|
||||
|
||||
buffer.append( LINE_SEPARATOR );
|
||||
}
|
||||
|
||||
private void writeRowsOn( StringBuilder buffer ) {
|
||||
int maxHeight = max( columns, BY_HEIGHT ).height();
|
||||
|
||||
for ( int i = 0; i < maxHeight; ++i )
|
||||
writeRowOn( buffer, i );
|
||||
}
|
||||
|
||||
private void writeRowOn( StringBuilder buffer, int rowIndex ) {
|
||||
for ( Iterator<Column> iter = columns.iterator(); iter.hasNext(); )
|
||||
iter.next().writeCellOn( rowIndex, buffer, iter.hasNext() );
|
||||
|
||||
buffer.append( LINE_SEPARATOR );
|
||||
}
|
||||
|
||||
private int arrayMax( int[] numbers ) {
|
||||
int maximum = MIN_VALUE;
|
||||
|
||||
for ( int each : numbers )
|
||||
maximum = Math.max( maximum, each );
|
||||
|
||||
return maximum;
|
||||
}
|
||||
|
||||
private int[] addRowCells( Object... rowData ) {
|
||||
int[] cellsAddedAt = new int[ rowData.length ];
|
||||
|
||||
Iterator<Column> iter = columns.iterator();
|
||||
for ( int i = 0; iter.hasNext() && i < rowData.length; ++i )
|
||||
cellsAddedAt[ i ] = iter.next().addCells( rowData[ i ] );
|
||||
|
||||
return cellsAddedAt;
|
||||
}
|
||||
|
||||
private void addPaddingCells( int... numberOfCellsAddedAt ) {
|
||||
int maxHeight = arrayMax( numberOfCellsAddedAt );
|
||||
|
||||
Iterator<Column> iter = columns.iterator();
|
||||
for ( int i = 0; iter.hasNext() && i < numberOfCellsAddedAt.length; ++i )
|
||||
addPaddingCellsForColumn( iter.next(), maxHeight, numberOfCellsAddedAt[ i ] );
|
||||
}
|
||||
|
||||
private void addPaddingCellsForColumn( Column column, int maxHeight, int numberOfCellsAdded ) {
|
||||
for ( int i = 0; i < maxHeight - numberOfCellsAdded; ++i )
|
||||
column.addCell( EMPTY );
|
||||
}
|
||||
}
|
56
src/joptsimple/internal/ConstructorInvokingValueConverter.java
Normale Datei
56
src/joptsimple/internal/ConstructorInvokingValueConverter.java
Normale Datei
@ -0,0 +1,56 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import joptsimple.ValueConverter;
|
||||
import static joptsimple.internal.Reflection.*;
|
||||
|
||||
/**
|
||||
* @param <V> constraint on the type of values being converted to
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ConstructorInvokingValueConverter.java,v 1.4 2009/10/25 18:37:08 pholser Exp $
|
||||
*/
|
||||
class ConstructorInvokingValueConverter<V> implements ValueConverter<V> {
|
||||
private final Constructor<V> ctor;
|
||||
|
||||
ConstructorInvokingValueConverter( Constructor<V> ctor ) {
|
||||
this.ctor = ctor;
|
||||
}
|
||||
|
||||
public V convert( String value ) {
|
||||
return instantiate( ctor, value );
|
||||
}
|
||||
|
||||
public Class<V> valueType() {
|
||||
return ctor.getDeclaringClass();
|
||||
}
|
||||
|
||||
public String valuePattern() {
|
||||
return null;
|
||||
}
|
||||
}
|
58
src/joptsimple/internal/MethodInvokingValueConverter.java
Normale Datei
58
src/joptsimple/internal/MethodInvokingValueConverter.java
Normale Datei
@ -0,0 +1,58 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import joptsimple.ValueConverter;
|
||||
import static joptsimple.internal.Reflection.*;
|
||||
|
||||
/**
|
||||
* @param <V> constraint on the type of values being converted to
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: MethodInvokingValueConverter.java,v 1.4 2009/10/25 18:37:08 pholser Exp $
|
||||
*/
|
||||
class MethodInvokingValueConverter<V> implements ValueConverter<V> {
|
||||
private final Method method;
|
||||
private final Class<V> clazz;
|
||||
|
||||
MethodInvokingValueConverter( Method method, Class<V> clazz ) {
|
||||
this.method = method;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public V convert( String value ) {
|
||||
return clazz.cast( invoke( method, value ) );
|
||||
}
|
||||
|
||||
public Class<V> valueType() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public String valuePattern() {
|
||||
return null;
|
||||
}
|
||||
}
|
51
src/joptsimple/internal/Objects.java
Normale Datei
51
src/joptsimple/internal/Objects.java
Normale Datei
@ -0,0 +1,51 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: Objects.java,v 1.2 2009/10/25 18:37:08 pholser Exp $
|
||||
*/
|
||||
public final class Objects {
|
||||
static {
|
||||
new Objects();
|
||||
}
|
||||
|
||||
private Objects() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects {@code null} references.
|
||||
*
|
||||
* @param target reference to check
|
||||
* @throws NullPointerException if {@code target} is {@code null}
|
||||
*/
|
||||
public static void ensureNotNull( Object target ) {
|
||||
if ( target == null )
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
142
src/joptsimple/internal/Reflection.java
Normale Datei
142
src/joptsimple/internal/Reflection.java
Normale Datei
@ -0,0 +1,142 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import static java.lang.reflect.Modifier.*;
|
||||
|
||||
import joptsimple.ValueConverter;
|
||||
|
||||
/**
|
||||
* <p>Helper methods for reflection.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: Reflection.java,v 1.20 2009/09/28 01:12:48 pholser Exp $
|
||||
*/
|
||||
public final class Reflection {
|
||||
static {
|
||||
new Reflection();
|
||||
}
|
||||
|
||||
private Reflection() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an appropriate value converter for the given class.
|
||||
*
|
||||
* @param <V> a constraint on the class object to introspect
|
||||
* @param clazz class to introspect on
|
||||
* @return a converter method or constructor
|
||||
*/
|
||||
public static <V> ValueConverter<V> findConverter( Class<V> clazz ) {
|
||||
ValueConverter<V> valueOf = valueOfConverter( clazz );
|
||||
if ( valueOf != null )
|
||||
return valueOf;
|
||||
|
||||
ValueConverter<V> constructor = constructorConverter( clazz );
|
||||
if ( constructor != null )
|
||||
return constructor;
|
||||
|
||||
throw new IllegalArgumentException( clazz + " is not a value type" );
|
||||
}
|
||||
|
||||
private static <V> ValueConverter<V> valueOfConverter( Class<V> clazz ) {
|
||||
try {
|
||||
Method valueOf = clazz.getDeclaredMethod( "valueOf", String.class );
|
||||
if ( !meetsConverterRequirements( valueOf, clazz ) )
|
||||
return null;
|
||||
|
||||
return new MethodInvokingValueConverter<V>( valueOf, clazz );
|
||||
}
|
||||
catch ( NoSuchMethodException ignored ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static <V> ValueConverter<V> constructorConverter( Class<V> clazz ) {
|
||||
try {
|
||||
return new ConstructorInvokingValueConverter<V>(
|
||||
clazz.getConstructor( String.class ) );
|
||||
}
|
||||
catch ( NoSuchMethodException ignored ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given constructor with the given arguments.
|
||||
*
|
||||
* @param <T> constraint on the type of the objects yielded by the constructor
|
||||
* @param constructor constructor to invoke
|
||||
* @param args arguments to hand to the constructor
|
||||
* @return the result of invoking the constructor
|
||||
* @throws ReflectionException in lieu of the gaggle of reflection-related exceptions
|
||||
*/
|
||||
public static <T> T instantiate( Constructor<T> constructor, Object... args ) {
|
||||
try {
|
||||
return constructor.newInstance( args );
|
||||
}
|
||||
catch ( Exception ex ) {
|
||||
throw reflectionException( ex );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given static method with the given arguments.
|
||||
*
|
||||
* @param method method to invoke
|
||||
* @param args arguments to hand to the method
|
||||
* @return the result of invoking the method
|
||||
* @throws ReflectionException in lieu of the gaggle of reflection-related exceptions
|
||||
*/
|
||||
public static Object invoke( Method method, Object... args ) {
|
||||
try {
|
||||
return method.invoke( null, args );
|
||||
}
|
||||
catch ( Exception ex ) {
|
||||
throw reflectionException( ex );
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean meetsConverterRequirements( Method method, Class<?> expectedReturnType ) {
|
||||
int modifiers = method.getModifiers();
|
||||
return isPublic( modifiers ) && isStatic( modifiers ) && expectedReturnType.equals( method.getReturnType() );
|
||||
}
|
||||
|
||||
private static RuntimeException reflectionException( Exception ex ) {
|
||||
if ( ex instanceof IllegalArgumentException )
|
||||
return new ReflectionException( ex );
|
||||
if ( ex instanceof InvocationTargetException )
|
||||
return new ReflectionException( ex.getCause() );
|
||||
if ( ex instanceof RuntimeException )
|
||||
return (RuntimeException) ex;
|
||||
|
||||
return new ReflectionException( ex );
|
||||
}
|
||||
}
|
40
src/joptsimple/internal/ReflectionException.java
Normale Datei
40
src/joptsimple/internal/ReflectionException.java
Normale Datei
@ -0,0 +1,40 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
/**
|
||||
* <p>This unchecked exception wraps reflection-oriented exceptions.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: ReflectionException.java,v 1.5 2009/08/13 00:34:36 pholser Exp $
|
||||
*/
|
||||
public class ReflectionException extends RuntimeException {
|
||||
private static final long serialVersionUID = -2L;
|
||||
|
||||
ReflectionException( Throwable cause ) {
|
||||
super( cause.toString() );
|
||||
}
|
||||
}
|
124
src/joptsimple/internal/Strings.java
Normale Datei
124
src/joptsimple/internal/Strings.java
Normale Datei
@ -0,0 +1,124 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import static java.lang.System.*;
|
||||
import static java.util.Arrays.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: Strings.java,v 1.16 2009/08/13 01:05:35 pholser Exp $
|
||||
*/
|
||||
public final class Strings {
|
||||
public static final String EMPTY = "";
|
||||
public static final String SINGLE_QUOTE = "'";
|
||||
public static final String LINE_SEPARATOR = getProperty( "line.separator" );
|
||||
|
||||
static {
|
||||
new Strings();
|
||||
}
|
||||
|
||||
private Strings() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gives a string consisting of the given character repeated the given number of
|
||||
* times.</p>
|
||||
*
|
||||
* @param ch the character to repeat
|
||||
* @param count how many times to repeat the character
|
||||
* @return the resultant string
|
||||
*/
|
||||
public static String repeat( char ch, int count ) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
buffer.append( ch );
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tells whether the given string is either {@code} or consists solely of
|
||||
* whitespace characters.</p>
|
||||
*
|
||||
* @param target string to check
|
||||
* @return {@code true} if the target string is null or empty
|
||||
*/
|
||||
public static boolean isNullOrEmpty( String target ) {
|
||||
return target == null || EMPTY.equals( target );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Gives a string consisting of a given string prepended and appended with
|
||||
* surrounding characters.</p>
|
||||
*
|
||||
* @param target a string
|
||||
* @param begin character to prepend
|
||||
* @param end character to append
|
||||
* @return the surrounded string
|
||||
*/
|
||||
public static String surround( String target, char begin, char end ) {
|
||||
return begin + target + end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a string consisting of the elements of a given array of strings, each
|
||||
* separated by a given separator string.
|
||||
*
|
||||
* @param pieces the strings to join
|
||||
* @param separator the separator
|
||||
* @return the joined string
|
||||
*/
|
||||
public static String join( String[] pieces, String separator ) {
|
||||
return join( asList( pieces ), separator );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a string consisting of the string representations of the elements of a
|
||||
* given array of objects, each separated by a given separator string.
|
||||
*
|
||||
* @param pieces the elements whose string representations are to be joined
|
||||
* @param separator the separator
|
||||
* @return the joined string
|
||||
*/
|
||||
public static String join( List<String> pieces, String separator ) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
for ( Iterator<String> iter = pieces.iterator(); iter.hasNext(); ) {
|
||||
buffer.append( iter.next() );
|
||||
|
||||
if ( iter.hasNext() )
|
||||
buffer.append( separator );
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
101
src/joptsimple/util/DateConverter.java
Normale Datei
101
src/joptsimple/util/DateConverter.java
Normale Datei
@ -0,0 +1,101 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.util;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import joptsimple.ValueConversionException;
|
||||
import joptsimple.ValueConverter;
|
||||
|
||||
/**
|
||||
* Converts values to {@link Date}s using a {@link DateFormat} object.
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: DateConverter.java,v 1.6 2009/10/25 18:37:09 pholser Exp $
|
||||
*/
|
||||
public class DateConverter implements ValueConverter<Date> {
|
||||
private final DateFormat formatter;
|
||||
|
||||
/**
|
||||
* Creates a converter that uses the given date formatter/parser.
|
||||
*
|
||||
* @param formatter the formatter/parser to use
|
||||
* @throws NullPointerException if {@code formatter} is {@code null}
|
||||
*/
|
||||
public DateConverter( DateFormat formatter ) {
|
||||
if ( formatter == null )
|
||||
throw new NullPointerException( "illegal null formatter" );
|
||||
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a converter that uses a {@link SimpleDateFormat} with the given date/time
|
||||
* pattern. The date formatter created is not
|
||||
* {@link SimpleDateFormat#setLenient(boolean) lenient}.
|
||||
*
|
||||
* @param pattern expected date/time pattern
|
||||
* @return the new converter
|
||||
* @throws NullPointerException if {@code pattern} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code pattern} is invalid
|
||||
*/
|
||||
public static DateConverter datePattern( String pattern ) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat( pattern );
|
||||
formatter.setLenient( false );
|
||||
|
||||
return new DateConverter( formatter );
|
||||
}
|
||||
|
||||
public Date convert( String value ) {
|
||||
ParsePosition position = new ParsePosition( 0 );
|
||||
|
||||
Date date = formatter.parse( value, position );
|
||||
if ( position.getIndex() != value.length() )
|
||||
throw new ValueConversionException( message( value ) );
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
public Class<Date> valueType() {
|
||||
return Date.class;
|
||||
}
|
||||
|
||||
public String valuePattern() {
|
||||
return formatter instanceof SimpleDateFormat
|
||||
? ( (SimpleDateFormat) formatter ).toLocalizedPattern()
|
||||
: "";
|
||||
}
|
||||
|
||||
private String message( String value ) {
|
||||
String message = "Value [" + value + "] does not match date/time pattern";
|
||||
if ( formatter instanceof SimpleDateFormat )
|
||||
message += " [" + ( (SimpleDateFormat) formatter ).toLocalizedPattern() + ']';
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
84
src/joptsimple/util/KeyValuePair.java
Normale Datei
84
src/joptsimple/util/KeyValuePair.java
Normale Datei
@ -0,0 +1,84 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.util;
|
||||
|
||||
import static joptsimple.internal.Strings.*;
|
||||
|
||||
/**
|
||||
* <p>A simple string key/string value pair.</p>
|
||||
*
|
||||
* <p>This is useful as an argument type for options whose values take on the form
|
||||
* <kbd>key=value</kbd>, such as JVM command line system properties.</p>
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: KeyValuePair.java,v 1.10 2009/10/25 18:37:09 pholser Exp $
|
||||
*/
|
||||
public final class KeyValuePair {
|
||||
public final String key;
|
||||
public final String value;
|
||||
|
||||
private KeyValuePair( String key, String value ) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string assumed to be of the form <kbd>key=value</kbd> into its parts.
|
||||
*
|
||||
* @param asString key-value string
|
||||
* @return a key-value pair
|
||||
* @throws NullPointerException if {@code stringRepresentation} is {@code null}
|
||||
*/
|
||||
public static KeyValuePair valueOf( String asString ) {
|
||||
int equalsIndex = asString.indexOf( '=' );
|
||||
if ( equalsIndex == -1 )
|
||||
return new KeyValuePair( asString, EMPTY );
|
||||
|
||||
String aKey = asString.substring( 0, equalsIndex );
|
||||
String aValue = equalsIndex == asString.length() - 1 ? EMPTY : asString.substring( equalsIndex + 1 );
|
||||
|
||||
return new KeyValuePair( aKey, aValue );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object that ) {
|
||||
if ( !( that instanceof KeyValuePair ) )
|
||||
return false;
|
||||
|
||||
KeyValuePair other = (KeyValuePair) that;
|
||||
return key.equals( other.key ) && value.equals( other.value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode() ^ value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + '=' + value;
|
||||
}
|
||||
}
|
86
src/joptsimple/util/RegexMatcher.java
Normale Datei
86
src/joptsimple/util/RegexMatcher.java
Normale Datei
@ -0,0 +1,86 @@
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2009 Paul R. Holser, Jr.
|
||||
|
||||
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 joptsimple.util;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import static java.util.regex.Pattern.*;
|
||||
|
||||
import joptsimple.ValueConversionException;
|
||||
import joptsimple.ValueConverter;
|
||||
|
||||
/**
|
||||
* Ensures that values entirely match a regular expression.
|
||||
*
|
||||
* @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
|
||||
* @version $Id: RegexMatcher.java,v 1.6 2009/10/25 18:37:09 pholser Exp $
|
||||
*/
|
||||
public class RegexMatcher implements ValueConverter<String> {
|
||||
private final Pattern pattern;
|
||||
|
||||
/**
|
||||
* Creates a matcher that uses the given regular expression, modified by the given
|
||||
* flags.
|
||||
*
|
||||
* @param pattern the regular expression pattern
|
||||
* @param flags modifying regex flags
|
||||
* @throws IllegalArgumentException if bit values other than those corresponding to
|
||||
* the defined match flags are set in {@code flags}
|
||||
* @throws java.util.regex.PatternSyntaxException if the expression's syntax is
|
||||
* invalid
|
||||
*/
|
||||
public RegexMatcher( String pattern, int flags ) {
|
||||
this.pattern = compile( pattern, flags );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a matcher that uses the given regular expression.
|
||||
*
|
||||
* @param pattern the regular expression pattern
|
||||
* @return the new converter
|
||||
* @throws java.util.regex.PatternSyntaxException if the expression's syntax is
|
||||
* invalid
|
||||
*/
|
||||
public static ValueConverter<String> regex( String pattern ) {
|
||||
return new RegexMatcher( pattern, 0 );
|
||||
}
|
||||
|
||||
public String convert( String value ) {
|
||||
if ( !pattern.matcher( value ).matches() ) {
|
||||
throw new ValueConversionException(
|
||||
"Value [" + value + "] did not match regex [" + pattern.pattern() + ']' );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public Class<String> valueType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public String valuePattern() {
|
||||
return pattern.pattern();
|
||||
}
|
||||
}
|
81
src/org/jnbt/ByteArrayTag.java
Normale Datei
81
src/org/jnbt/ByteArrayTag.java
Normale Datei
@ -0,0 +1,81 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Byte_Array</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ByteArrayTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final byte[] value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public ByteArrayTag(String name, byte[] value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder hex = new StringBuilder();
|
||||
for(byte b : value) {
|
||||
String hexDigits = Integer.toHexString(b).toUpperCase();
|
||||
if(hexDigits.length() == 1) {
|
||||
hex.append("0");
|
||||
}
|
||||
hex.append(hexDigits).append(" ");
|
||||
}
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Byte_Array" + append + ": " + hex.toString();
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/ByteTag.java
Normale Datei
73
src/org/jnbt/ByteTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Byte</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ByteTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final byte value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public ByteTag(String name, byte value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Byte" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
82
src/org/jnbt/CompoundTag.java
Normale Datei
82
src/org/jnbt/CompoundTag.java
Normale Datei
@ -0,0 +1,82 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Compound</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class CompoundTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final Map<String, Tag> value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public CompoundTag(String name, Map<String, Tag> value) {
|
||||
super(name);
|
||||
this.value = Collections.unmodifiableMap(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Tag> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("TAG_Compound" + append + ": " + value.size() + " entries\r\n{\r\n");
|
||||
for(Map.Entry<String, Tag> entry : value.entrySet()) {
|
||||
bldr.append(" " + entry.getValue().toString().replaceAll("\r\n", "\r\n ") + "\r\n");
|
||||
}
|
||||
bldr.append("}");
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/DoubleTag.java
Normale Datei
73
src/org/jnbt/DoubleTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Double</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class DoubleTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final double value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public DoubleTag(String name, double value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Double" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
60
src/org/jnbt/EndTag.java
Normale Datei
60
src/org/jnbt/EndTag.java
Normale Datei
@ -0,0 +1,60 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_End</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class EndTag extends Tag {
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*/
|
||||
public EndTag() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TAG_End";
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/FloatTag.java
Normale Datei
73
src/org/jnbt/FloatTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Float</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class FloatTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final float value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public FloatTag(String name, float value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Float" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/IntTag.java
Normale Datei
73
src/org/jnbt/IntTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Int</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class IntTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public IntTag(String name, int value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Int" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
97
src/org/jnbt/ListTag.java
Normale Datei
97
src/org/jnbt/ListTag.java
Normale Datei
@ -0,0 +1,97 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The <code>TAG_List</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ListTag extends Tag {
|
||||
|
||||
/**
|
||||
* The type.
|
||||
*/
|
||||
private final Class<? extends Tag> type;
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final List<Tag> value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param type The type of item in the list.
|
||||
* @param value The value.
|
||||
*/
|
||||
public ListTag(String name, Class<? extends Tag> type, List<Tag> value) {
|
||||
super(name);
|
||||
this.type = type;
|
||||
this.value = Collections.unmodifiableList(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of item in this list.
|
||||
* @return The type of item in this list.
|
||||
*/
|
||||
public Class<? extends Tag> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("TAG_List" + append + ": " + value.size() + " entries of type " + NBTUtils.getTypeName(type) + "\r\n{\r\n");
|
||||
for(Tag t : value) {
|
||||
bldr.append(" " + t.toString().replaceAll("\r\n", "\r\n ") + "\r\n");
|
||||
}
|
||||
bldr.append("}");
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/LongTag.java
Normale Datei
73
src/org/jnbt/LongTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Long</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class LongTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final long value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public LongTag(String name, long value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Long" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
72
src/org/jnbt/NBTConstants.java
Normale Datei
72
src/org/jnbt/NBTConstants.java
Normale Datei
@ -0,0 +1,72 @@
|
||||
package org.jnbt;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class which holds constant values.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTConstants {
|
||||
|
||||
/**
|
||||
* The character set used by NBT (UTF-8).
|
||||
*/
|
||||
public static final Charset CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
/**
|
||||
* Tag type constants.
|
||||
*/
|
||||
public static final int TYPE_END = 0,
|
||||
TYPE_BYTE = 1,
|
||||
TYPE_SHORT = 2,
|
||||
TYPE_INT = 3,
|
||||
TYPE_LONG = 4,
|
||||
TYPE_FLOAT = 5,
|
||||
TYPE_DOUBLE = 6,
|
||||
TYPE_BYTE_ARRAY = 7,
|
||||
TYPE_STRING = 8,
|
||||
TYPE_LIST = 9,
|
||||
TYPE_COMPOUND = 10;
|
||||
|
||||
/**
|
||||
* Default private constructor.
|
||||
*/
|
||||
private NBTConstants() {
|
||||
|
||||
}
|
||||
|
||||
}
|
179
src/org/jnbt/NBTInputStream.java
Normale Datei
179
src/org/jnbt/NBTInputStream.java
Normale Datei
@ -0,0 +1,179 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* <p>This class reads <strong>NBT</strong>, or
|
||||
* <strong>Named Binary Tag</strong> streams, and produces an object graph of
|
||||
* subclasses of the <code>Tag</code> object.</p>
|
||||
*
|
||||
* <p>The NBT format was created by Markus Persson, and the specification may
|
||||
* be found at <a href="http://www.minecraft.net/docs/NBT.txt">
|
||||
* http://www.minecraft.net/docs/NBT.txt</a>.</p>
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTInputStream implements Closeable {
|
||||
|
||||
/**
|
||||
* The data input stream.
|
||||
*/
|
||||
private final DataInputStream is;
|
||||
|
||||
/**
|
||||
* Creates a new <code>NBTInputStream</code>, which will source its data
|
||||
* from the specified input stream.
|
||||
* @param is The input stream.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public NBTInputStream(InputStream is) throws IOException {
|
||||
this.is = new DataInputStream(new GZIPInputStream(is));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an NBT tag from the stream.
|
||||
* @return The tag that was read.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public Tag readTag() throws IOException {
|
||||
return readTag(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an NBT from the stream.
|
||||
* @param depth The depth of this tag.
|
||||
* @return The tag that was read.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private Tag readTag(int depth) throws IOException {
|
||||
int type = is.readByte() & 0xFF;
|
||||
|
||||
String name;
|
||||
if(type != NBTConstants.TYPE_END) {
|
||||
int nameLength = is.readShort() & 0xFFFF;
|
||||
byte[] nameBytes = new byte[nameLength];
|
||||
is.readFully(nameBytes);
|
||||
name = new String(nameBytes, NBTConstants.CHARSET);
|
||||
} else {
|
||||
name = "";
|
||||
}
|
||||
|
||||
return readTagPayload(type, name, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the payload of a tag, given the name and type.
|
||||
* @param type The type.
|
||||
* @param name The name.
|
||||
* @param depth The depth.
|
||||
* @return The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private Tag readTagPayload(int type, String name, int depth) throws IOException {
|
||||
switch(type) {
|
||||
case NBTConstants.TYPE_END:
|
||||
if(depth == 0) {
|
||||
throw new IOException("TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
|
||||
} else {
|
||||
return new EndTag();
|
||||
}
|
||||
case NBTConstants.TYPE_BYTE:
|
||||
return new ByteTag(name, is.readByte());
|
||||
case NBTConstants.TYPE_SHORT:
|
||||
return new ShortTag(name, is.readShort());
|
||||
case NBTConstants.TYPE_INT:
|
||||
return new IntTag(name, is.readInt());
|
||||
case NBTConstants.TYPE_LONG:
|
||||
return new LongTag(name, is.readLong());
|
||||
case NBTConstants.TYPE_FLOAT:
|
||||
return new FloatTag(name, is.readFloat());
|
||||
case NBTConstants.TYPE_DOUBLE:
|
||||
return new DoubleTag(name, is.readDouble());
|
||||
case NBTConstants.TYPE_BYTE_ARRAY:
|
||||
int length = is.readInt();
|
||||
byte[] bytes = new byte[length];
|
||||
is.readFully(bytes);
|
||||
return new ByteArrayTag(name, bytes);
|
||||
case NBTConstants.TYPE_STRING:
|
||||
length = is.readShort();
|
||||
bytes = new byte[length];
|
||||
is.readFully(bytes);
|
||||
return new StringTag(name, new String(bytes, NBTConstants.CHARSET));
|
||||
case NBTConstants.TYPE_LIST:
|
||||
int childType = is.readByte();
|
||||
length = is.readInt();
|
||||
|
||||
List<Tag> tagList = new ArrayList<Tag>();
|
||||
for(int i = 0; i < length; i++) {
|
||||
Tag tag = readTagPayload(childType, "", depth + 1);
|
||||
if(tag instanceof EndTag) {
|
||||
throw new IOException("TAG_End not permitted in a list.");
|
||||
}
|
||||
tagList.add(tag);
|
||||
}
|
||||
|
||||
return new ListTag(name, NBTUtils.getTypeClass(childType), tagList);
|
||||
case NBTConstants.TYPE_COMPOUND:
|
||||
Map<String, Tag> tagMap = new HashMap<String, Tag>();
|
||||
while(true) {
|
||||
Tag tag = readTag(depth + 1);
|
||||
if(tag instanceof EndTag) {
|
||||
break;
|
||||
} else {
|
||||
tagMap.put(tag.getName(), tag);
|
||||
}
|
||||
}
|
||||
|
||||
return new CompoundTag(name, tagMap);
|
||||
default:
|
||||
throw new IOException("Invalid tag type: " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
is.close();
|
||||
}
|
||||
|
||||
}
|
257
src/org/jnbt/NBTOutputStream.java
Normale Datei
257
src/org/jnbt/NBTOutputStream.java
Normale Datei
@ -0,0 +1,257 @@
|
||||
package org.jnbt;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>This class writes <strong>NBT</strong>, or
|
||||
* <strong>Named Binary Tag</strong> <code>Tag</code> objects to an underlying
|
||||
* <code>OutputStream</code>.</p>
|
||||
*
|
||||
* <p>The NBT format was created by Markus Persson, and the specification may
|
||||
* be found at <a href="http://www.minecraft.net/docs/NBT.txt">
|
||||
* http://www.minecraft.net/docs/NBT.txt</a>.</p>
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTOutputStream implements Closeable {
|
||||
|
||||
/**
|
||||
* The output stream.
|
||||
*/
|
||||
private final DataOutputStream os;
|
||||
|
||||
/**
|
||||
* Creates a new <code>NBTOutputStream</code>, which will write data to the
|
||||
* specified underlying output stream.
|
||||
* @param os The output stream.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public NBTOutputStream(OutputStream os) throws IOException {
|
||||
this.os = new DataOutputStream(new GZIPOutputStream(os));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a tag.
|
||||
* @param tag The tag to write.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public void writeTag(Tag tag) throws IOException {
|
||||
int type = NBTUtils.getTypeCode(tag.getClass());
|
||||
String name = tag.getName();
|
||||
byte[] nameBytes = name.getBytes(NBTConstants.CHARSET);
|
||||
|
||||
os.writeByte(type);
|
||||
os.writeShort(nameBytes.length);
|
||||
os.write(nameBytes);
|
||||
|
||||
if(type == NBTConstants.TYPE_END) {
|
||||
throw new IOException("Named TAG_End not permitted.");
|
||||
}
|
||||
|
||||
writeTagPayload(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes tag payload.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeTagPayload(Tag tag) throws IOException {
|
||||
int type = NBTUtils.getTypeCode(tag.getClass());
|
||||
switch(type) {
|
||||
case NBTConstants.TYPE_END:
|
||||
writeEndTagPayload((EndTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_BYTE:
|
||||
writeByteTagPayload((ByteTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_SHORT:
|
||||
writeShortTagPayload((ShortTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_INT:
|
||||
writeIntTagPayload((IntTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_LONG:
|
||||
writeLongTagPayload((LongTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_FLOAT:
|
||||
writeFloatTagPayload((FloatTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_DOUBLE:
|
||||
writeDoubleTagPayload((DoubleTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_BYTE_ARRAY:
|
||||
writeByteArrayTagPayload((ByteArrayTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_STRING:
|
||||
writeStringTagPayload((StringTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_LIST:
|
||||
writeListTagPayload((ListTag) tag);
|
||||
break;
|
||||
case NBTConstants.TYPE_COMPOUND:
|
||||
writeCompoundTagPayload((CompoundTag) tag);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Invalid tag type: " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Byte</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeByteTagPayload(ByteTag tag) throws IOException {
|
||||
os.writeByte(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Byte_Array</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException {
|
||||
byte[] bytes = tag.getValue();
|
||||
os.writeInt(bytes.length);
|
||||
os.write(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Compound</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeCompoundTagPayload(CompoundTag tag) throws IOException {
|
||||
for(Tag childTag : tag.getValue().values()) {
|
||||
writeTag(childTag);
|
||||
}
|
||||
os.writeByte((byte) 0); // end tag - better way?
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_List</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeListTagPayload(ListTag tag) throws IOException {
|
||||
Class<? extends Tag> clazz = tag.getType();
|
||||
List<Tag> tags = tag.getValue();
|
||||
int size = tags.size();
|
||||
|
||||
os.writeByte(NBTUtils.getTypeCode(clazz));
|
||||
os.writeInt(size);
|
||||
for(int i = 0; i < size; i++) {
|
||||
writeTagPayload(tags.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_String</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeStringTagPayload(StringTag tag) throws IOException {
|
||||
byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET);
|
||||
os.writeShort(bytes.length);
|
||||
os.write(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Double</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeDoubleTagPayload(DoubleTag tag) throws IOException {
|
||||
os.writeDouble(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Float</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeFloatTagPayload(FloatTag tag) throws IOException {
|
||||
os.writeFloat(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Long</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeLongTagPayload(LongTag tag) throws IOException {
|
||||
os.writeLong(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Int</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeIntTagPayload(IntTag tag) throws IOException {
|
||||
os.writeInt(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Short</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeShortTagPayload(ShortTag tag) throws IOException {
|
||||
os.writeShort(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Empty</code> tag.
|
||||
* @param tag The tag.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeEndTagPayload(EndTag tag) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
os.close();
|
||||
}
|
||||
|
||||
}
|
152
src/org/jnbt/NBTUtils.java
Normale Datei
152
src/org/jnbt/NBTUtils.java
Normale Datei
@ -0,0 +1,152 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class which contains NBT-related utility methods.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTUtils {
|
||||
|
||||
/**
|
||||
* Gets the type name of a tag.
|
||||
* @param clazz The tag class.
|
||||
* @return The type name.
|
||||
*/
|
||||
public static String getTypeName(Class<? extends Tag> clazz) {
|
||||
if(clazz.equals(ByteArrayTag.class)) {
|
||||
return "TAG_Byte_Array";
|
||||
} else if(clazz.equals(ByteTag.class)) {
|
||||
return "TAG_Byte";
|
||||
} else if(clazz.equals(CompoundTag.class)) {
|
||||
return "TAG_Compound";
|
||||
} else if(clazz.equals(DoubleTag.class)) {
|
||||
return "TAG_Double";
|
||||
} else if(clazz.equals(EndTag.class)) {
|
||||
return "TAG_End";
|
||||
} else if(clazz.equals(FloatTag.class)) {
|
||||
return "TAG_Float";
|
||||
} else if(clazz.equals(IntTag.class)) {
|
||||
return "TAG_Int";
|
||||
} else if(clazz.equals(ListTag.class)) {
|
||||
return "TAG_List";
|
||||
} else if(clazz.equals(LongTag.class)) {
|
||||
return "TAG_Long";
|
||||
} else if(clazz.equals(ShortTag.class)) {
|
||||
return "TAG_Short";
|
||||
} else if(clazz.equals(StringTag.class)) {
|
||||
return "TAG_String";
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid tag classs (" + clazz.getName() + ").");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type code of a tag class.
|
||||
* @param clazz The tag class.
|
||||
* @return The type code.
|
||||
* @throws IllegalArgumentException if the tag class is invalid.
|
||||
*/
|
||||
public static int getTypeCode(Class<? extends Tag> clazz) {
|
||||
if(clazz.equals(ByteArrayTag.class)) {
|
||||
return NBTConstants.TYPE_BYTE_ARRAY;
|
||||
} else if(clazz.equals(ByteTag.class)) {
|
||||
return NBTConstants.TYPE_BYTE;
|
||||
} else if(clazz.equals(CompoundTag.class)) {
|
||||
return NBTConstants.TYPE_COMPOUND;
|
||||
} else if(clazz.equals(DoubleTag.class)) {
|
||||
return NBTConstants.TYPE_DOUBLE;
|
||||
} else if(clazz.equals(EndTag.class)) {
|
||||
return NBTConstants.TYPE_END;
|
||||
} else if(clazz.equals(FloatTag.class)) {
|
||||
return NBTConstants.TYPE_FLOAT;
|
||||
} else if(clazz.equals(IntTag.class)) {
|
||||
return NBTConstants.TYPE_INT;
|
||||
} else if(clazz.equals(ListTag.class)) {
|
||||
return NBTConstants.TYPE_LIST;
|
||||
} else if(clazz.equals(LongTag.class)) {
|
||||
return NBTConstants.TYPE_LONG;
|
||||
} else if(clazz.equals(ShortTag.class)) {
|
||||
return NBTConstants.TYPE_SHORT;
|
||||
} else if(clazz.equals(StringTag.class)) {
|
||||
return NBTConstants.TYPE_STRING;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid tag classs (" + clazz.getName() + ").");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class of a type of tag.
|
||||
* @param type The type.
|
||||
* @return The class.
|
||||
* @throws IllegalArgumentException if the tag type is invalid.
|
||||
*/
|
||||
public static Class<? extends Tag> getTypeClass(int type) {
|
||||
switch(type) {
|
||||
case NBTConstants.TYPE_END:
|
||||
return EndTag.class;
|
||||
case NBTConstants.TYPE_BYTE:
|
||||
return ByteTag.class;
|
||||
case NBTConstants.TYPE_SHORT:
|
||||
return ShortTag.class;
|
||||
case NBTConstants.TYPE_INT:
|
||||
return IntTag.class;
|
||||
case NBTConstants.TYPE_LONG:
|
||||
return LongTag.class;
|
||||
case NBTConstants.TYPE_FLOAT:
|
||||
return FloatTag.class;
|
||||
case NBTConstants.TYPE_DOUBLE:
|
||||
return DoubleTag.class;
|
||||
case NBTConstants.TYPE_BYTE_ARRAY:
|
||||
return ByteArrayTag.class;
|
||||
case NBTConstants.TYPE_STRING:
|
||||
return StringTag.class;
|
||||
case NBTConstants.TYPE_LIST:
|
||||
return ListTag.class;
|
||||
case NBTConstants.TYPE_COMPOUND:
|
||||
return CompoundTag.class;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid tag type : " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default private constructor.
|
||||
*/
|
||||
private NBTUtils() {
|
||||
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/ShortTag.java
Normale Datei
73
src/org/jnbt/ShortTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_Short</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ShortTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final short value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public ShortTag(String name, short value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Short" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
73
src/org/jnbt/StringTag.java
Normale Datei
73
src/org/jnbt/StringTag.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The <code>TAG_String</code> tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class StringTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
* @param name The name.
|
||||
* @param value The value.
|
||||
*/
|
||||
public StringTag(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if(name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_String" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
70
src/org/jnbt/Tag.java
Normale Datei
70
src/org/jnbt/Tag.java
Normale Datei
@ -0,0 +1,70 @@
|
||||
package org.jnbt;
|
||||
|
||||
/*
|
||||
* JNBT License
|
||||
*
|
||||
* Copyright (c) 2010 Graham Edgecombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the JNBT team nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a single NBT tag.
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public abstract class Tag {
|
||||
|
||||
/**
|
||||
* The name of this tag.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Creates the tag with the specified name.
|
||||
* @param name The name.
|
||||
*/
|
||||
public Tag(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this tag.
|
||||
* @return The name of this tag.
|
||||
*/
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this tag.
|
||||
* @return The value of this tag.
|
||||
*/
|
||||
public abstract Object getValue();
|
||||
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren