<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>bassistance.de</title>
	<atom:link href="http://bassistance.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://bassistance.de</link>
	<description>Jörn Zaefferer on Bass, Geeks and Rock'n'Roll</description>
	<lastBuildDate>Wed, 10 Mar 2010 22:49:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Release: Validation Plugin 1.7</title>
		<link>http://bassistance.de/2010/03/10/release-validation-plugin-1-7/</link>
		<comments>http://bassistance.de/2010/03/10/release-validation-plugin-1-7/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 22:49:14 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=615</guid>
		<description><![CDATA[An update for the jQuery validation plugin is available. Most important: Its now fully compatible with jQuery 1.4.2, and still fully compatible with jQuery 1.3.2. I didn&#8217;t test with 1.2.6, but it should work, too.
There are four new localizations: Lithuanian, Greek, Latvian and Hebrew. The Spanish localization got a few improvements (I fully trust my [...]]]></description>
			<content:encoded><![CDATA[<p>An update for the <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery validation plugin</a> is available. Most important: Its now fully compatible with jQuery 1.4.2, and still fully compatible with jQuery 1.3.2. I didn&#8217;t test with 1.2.6, but it should work, too.</p>
<p>There are four new localizations: Lithuanian, Greek, Latvian and Hebrew. The Spanish localization got a few improvements (I fully trust my contributors on that). Someone also contributed phoneUK and mobileUK methods, which can be found in <a href="http://jquery.bassistance.de/validate/additional-methods.js">additional-methods.js</a> (while adding those, I renamed the phone-method to phoneUS).</p>
<p>And as a first proof of concept, there is now a <a href="http://jquery.bassistance.de/validate/demo/themerollered.html">demo styled with jQuery UI Themeroller classes</a>. I&#8217;ll improve that when form support gets better in jQuery UI (planned for 1.9).</p>
<p><a href="http://jquery.bassistance.de/validate/jquery.validate.zip">Download this release.</a></p>
<p>The full changelog:</p>
<ul>
<li>Added Lithuanian (LT) localization</li>
<li>Added Greek (EL) localization (<a href="http://plugins.jquery.com/node/12319">http://plugins.jquery.com/node/12319</a>)</li>
<li>Added Latvian (LV) localization (<a href="http://plugins.jquery.com/node/12349">http://plugins.jquery.com/node/12349</a>)</li>
<li>Added Hebrew (HE) localization (<a href="http://plugins.jquery.com/node/12039">http://plugins.jquery.com/node/12039</a>)</li>
<li>Fixed Spanish (ES) localization (<a href="http://plugins.jquery.com/node/12696">http://plugins.jquery.com/node/12696</a>)</li>
<li>Added <a href="http://jquery.bassistance.de/validate/demo/themerollered.html">jQuery UI themerolled demo</a></li>
<li>Removed cmxform.js</li>
<li>Fixed four missing semicolons (<a href="http://plugins.jquery.com/node/12639">http://plugins.jquery.com/node/12639</a>)</li>
<li>Renamed phone-method in additional-methods.js to phoneUS</li>
<li>Added phoneUK and mobileUK methods to additional-methods.js (<a href="http://plugins.jquery.com/node/12359">http://plugins.jquery.com/node/12359</a>)</li>
<li>Deep extend options to avoid modifying multiple forms when using the rules-method on a single element (<a href="http://plugins.jquery.com/node/12411">http://plugins.jquery.com/node/12411</a>)</li>
<li>Bugfixes for compability with jQuery 1.4.2, while maintaining backwards-compability</li>
</ul>
<p>The right place for support changed a bit &#8211; the mailinglist is no more, replaced by a much cooler forum:</p>
<ul>
<li>Please post questions to the <a href="http://forum.jquery.com/using-jquery-plugins">official Using jQuery Plugins Forum</a>, tagging your question with (at least) &#8220;validate&#8221;. Keep your question short and succinct and provide code when possible; a testpage makes it much more likely that you get an useful answer in no time.</li>
<li>Please post bug reports and other contributions (enhancements, features, eg. new validation methods) to the <a href="http://plugins.jquery.com/project/issues/validate">plugins.jQuery.com bug tracker</a> (requires <a href="http://plugins.jquery.com/user/register">registration</a>).</li>
</ul>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2010/03/10/release-validation-plugin-1-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java Tricks: Find out who invoked you</title>
		<link>http://bassistance.de/2010/02/10/java-tricks-find-out-who-invoked-you/</link>
		<comments>http://bassistance.de/2010/02/10/java-tricks-find-out-who-invoked-you/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 13:10:58 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=613</guid>
		<description><![CDATA[There is a setting in the log4j framework that allows you to log the exact location of where the logger was invoked (I&#8217;d provide a link to the related documentation, but I can&#8217;t find it; the lo4j site is a horrible mess). I always wondered how that works, here&#8217;s how:
public class Invoker {

   [...]]]></description>
			<content:encoded><![CDATA[<p>There is a setting in the log4j framework that allows you to log the exact location of where the logger was invoked (I&#8217;d provide a link to the related documentation, but I can&#8217;t find it; the lo4j site is a horrible mess). I always wondered how that works, here&#8217;s how:</p>
<pre><code class="java">public class Invoker {

        public static void main(String[] args) {
                System.out.println("Invoked from: " + invoker());
                System.out.println("A bit more indirect: " + test());
        }

        private static String test() {
                return invoker();
        }

        public static String invoker() {
                try {
                        throw new RuntimeException();
                } catch(RuntimeException e) {
                        return e.getStackTrace()[1].toString();
                }
        }
}</code></pre>
<p>The output format matches the Exception#printStackTrace format, so that you can click on the result in the Eclipse console and it opens the file at the correct line:</p>
<pre><code>Invoked from: Invoker.main(Invoker.java:4)
A bit more indirect: Invoker.test(Invoker.java:9) </code></pre>
<p>Based on the comment attached to the code where I found this, there is an easier way to obtain the stack in Java 1.5. And with a bit of searching, I found the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#getStackTrace%28%29">getStackTrace method</a>, added to Thread in 1.5. With that, the code becomes even simpler:</p>
<pre><code>public class Invoker {

        public static void main(String[] args) {
                System.out.println("Invoked from: " + invoker());
                System.out.println("A bit more indirect: " + test());
        }

        private static String test() {
                return invoker();
        }

        public static String invoker() {
                return Thread.currentThread().getStackTrace()[2].toString();
        }

} </code></pre>
<p>Note that the call to Thread#getStackTrace ends up on the stack, too, so the interesting StackTraceElement is at index 2, not 1 as before.</p>
<p>A final warning: While this is immensly helpful for log-based debugging, the performance hit should be kept in mind. The log4j documentation warns about that as well, though I suspect that the Java 1.5 methods will have less impact than the try-catch approach. And some very primitive benchmarking proved me wrong&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2010/02/10/java-tricks-find-out-who-invoked-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Reboot?</title>
		<link>http://bassistance.de/2010/01/07/reboot/</link>
		<comments>http://bassistance.de/2010/01/07/reboot/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 23:09:25 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://bassistance.de/2010/01/07/reboot/</guid>
		<description><![CDATA[I&#8217;m thinking about rebooting this blog: Create a new .com site with my jQuery stuff and posting about technical/programming stuff there, while relaunching this site into a german blog, posting about non-technical stuff, music, politics&#8230;
If you read this, please let me know what you think: leave a comment, or send me a mail at joern.zaefferer@gmail.com
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m thinking about rebooting this blog: Create a new .com site with my jQuery stuff and posting about technical/programming stuff there, while relaunching this site into a german blog, posting about non-technical stuff, music, politics&#8230;</p>
<p>If you read this, please let me know what you think: leave a comment, or send me a mail at joern.zaefferer@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2010/01/07/reboot/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Wallraff Interview, Sozialdebatte, Religion</title>
		<link>http://bassistance.de/2009/12/21/wallraff-interview-sozialdebatte-religion/</link>
		<comments>http://bassistance.de/2009/12/21/wallraff-interview-sozialdebatte-religion/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 14:47:52 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Worth Reading]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=609</guid>
		<description><![CDATA[Hier sind drei Artikel auf zeit.de, ich die allesamt sehe empfehlen kann.
Zum einen ein Streitgespräch mit Günter Wallraff, zu dessen Buch Aus der schönen neuen Welt (ebenfalls sehr empfehlenswert) und den zugehörigen Film, Schwarz auf Weiss. Auch die am Ende erwähnte Titanic-Satire dazu lesen!
Dann wäre da ein Artikel zur Sozialdebatte, auch wenn in der URL [...]]]></description>
			<content:encoded><![CDATA[<p>Hier sind drei Artikel auf zeit.de, ich die allesamt sehe empfehlen kann.</p>
<p>Zum einen ein <a href="http://www.zeit.de/2009/52/Wallraff-im-Gespraech">Streitgespräch mit Günter Wallraff</a>, zu dessen Buch Aus der schönen neuen Welt (ebenfalls sehr empfehlenswert) und den zugehörigen Film, Schwarz auf Weiss. Auch die am Ende erwähnte <a href="http://www.titanic-magazin.de/fischer_ziegelwagner_wallraff.html">Titanic-Satire</a> dazu lesen!</p>
<p>Dann wäre da ein <a href="http://www.zeit.de/2009/52/Armutsdebatte">Artikel zur Sozialdebatte</a>, auch wenn in der URL Armutsdebatte steht. Es sollte schwer fallen, dem uneingeschränkt zuzustimmen, aber als Denkanstoß sehr gut.</p>
<p>Wieder was ganz anderes: Der <a href="http://www.zeit.de/2009/52/Beichtstuehle">Bericht von Jemand</a>, der wegen das Papstes aus der Kirche austreten will, und dies zunächst mit Pfarrern aus ganz Deutschland bei der Beichte bespricht.</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/12/21/wallraff-interview-sozialdebatte-religion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Technical issues</title>
		<link>http://bassistance.de/2009/12/20/technical-issues/</link>
		<comments>http://bassistance.de/2009/12/20/technical-issues/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 15:19:10 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://bassistance.de/2009/12/20/technical-issues/</guid>
		<description><![CDATA[The auto-update to 2.9 didn&#8217;t went that well, seems like Wordpress is choking on my wp-content folder. At least I managed to restore it to the default theme. That&#8217;ll have to do until I manage to reproduce and fix the error locally.
]]></description>
			<content:encoded><![CDATA[<p>The auto-update to 2.9 didn&#8217;t went that well, seems like Wordpress is choking on my wp-content folder. At least I managed to restore it to the default theme. That&#8217;ll have to do until I manage to reproduce and fix the error locally.</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/12/20/technical-issues/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Regex search-and-replace to add script elements to a lot of html files</title>
		<link>http://bassistance.de/2009/12/16/regex-search-and-replace-to-add-script-elements-to-a-lot-of-html-files/</link>
		<comments>http://bassistance.de/2009/12/16/regex-search-and-replace-to-add-script-elements-to-a-lot-of-html-files/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 22:12:15 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=602</guid>
		<description><![CDATA[I needed to add a script tag in every file that included jquery.ui.core.js, directly after that that existing element, with the same indentation. This is what worked quite nicely for me:
Search for: (\s+)&#60;script type=&#8221;text/javascript&#8221; src=&#8221;(.+)/ui/jquery.ui.core.js&#8221;&#62;&#60;/script&#62;
Replace with: $1&#60;script type=&#8221;text/javascript&#8221; src=&#8221;$2/ui/jquery.ui.core.js&#8221;&#62;&#60;/script&#62;$1&#60;script type=&#8221;text/javascript&#8221; src=&#8221;$2/ui/jquery.ui.widget.js&#8221;&#62;&#60;/script&#62;
It groups the whitespace in front of the script element as well as the &#8220;../../&#8221;-part, [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to add a script tag in every file that included jquery.ui.core.js, directly after that that existing element, with the same indentation. This is what worked quite nicely for me:</p>
<p>Search for: (\s+)&lt;script type=&#8221;text/javascript&#8221; src=&#8221;(.+)/ui/jquery.ui.core.js&#8221;&gt;&lt;/script&gt;</p>
<p>Replace with: $1&lt;script type=&#8221;text/javascript&#8221; src=&#8221;$2/ui/jquery.ui.core.js&#8221;&gt;&lt;/script&gt;$1&lt;script type=&#8221;text/javascript&#8221; src=&#8221;$2/ui/jquery.ui.widget.js&#8221;&gt;&lt;/script&gt;<script src="$2/ui/jquery.ui.widget.js" type="text/javascript"></script></p>
<p>It groups the whitespace in front of the script element as well as the &#8220;../../&#8221;-part, and then just duplicates it, inserting the matched groups.</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/12/16/regex-search-and-replace-to-add-script-elements-to-a-lot-of-html-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Release: Validation Plugin 1.6</title>
		<link>http://bassistance.de/2009/11/30/release-validation-plugin-1-6/</link>
		<comments>http://bassistance.de/2009/11/30/release-validation-plugin-1-6/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 21:36:42 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=591</guid>
		<description><![CDATA[Update update: Files are now availble via Microsoft&#8217;s AJAX CDN.
An update for the jQuery validation plugin is available. There are five new localizations (now at 26 in total), including Arabic and Farsi (both right-to-left). Validation of selects is now more interactive, click events are properly handled to provide quicker feedback (also a bug related to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update update</strong>: Files are now availble via Microsoft&#8217;s AJAX CDN.</p>
<p>An update for the <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery validation plugin</a> is available. There are five new localizations (now at 26 in total), including Arabic and Farsi (both right-to-left). Validation of selects is now more interactive, click events are properly handled to provide quicker feedback (also a bug related to selects in IE8 is fixed). The equalTo-method is now aware of changes to the target field, so a change to a password field will be reflected in a confirm-password field. And more&#8230;</p>
<p><a href="http://jquery.bassistance.de/validate/jquery.validate.zip">Download this release.</a></p>
<p>The only not fully backwards-compatible change (if you spot anything else, please <a href="http://plugins.jquery.com/project/issues/validate">report it as a bug</a>): The dateDE and numberDE methods were replaced with a localization/methods_de.js file, with localized versions of both the date and number methods. There are also localized methods for the NL and PT locales. The goal is to gather more localized versions of these, similar to the localized messages.</p>
<p>The full changelog:</p>
<ul>
<li>Added Arabic (AR), Portuguese (PTPT), Persian (FA), Finnish (FI) and Bulgarian (BR) localization</li>
<li>Updated Swedish (SE) localization (some missing html iso characters)</li>
<li>Fixed $.validator.addMethod to properly handle empty string vs. undefined for the message argument</li>
<li>Fixed two accidental global variables</li>
<li>Enhanced min/max/rangeWords (in additional-methods.js) to strip html before counting; good when counting words in a richtext editor</li>
<li>Added localized methods for DE, NL and PT, removing the dateDE and numberDE methods (use messages_de.js and methods_de.js with date and number methods instead)</li>
<li>Fixed remote form submit synchronization, kudos to Matas Petrikas</li>
<li>Improved interactive select validation, now validating also on click (via option or select, inconsistent across browsers); doesn&#8217;t work in Safari, which doesn&#8217;t trigger a click event at all on select elements; fixes <a href="http://plugins.jquery.com/node/11520">http://plugins.jquery.com/node/11520</a></li>
<li>Updated to latest form plugin (2.36), fixing <a href="http://plugins.jquery.com/node/11487">http://plugins.jquery.com/node/11487</a></li>
<li>Bind to blur event for equalTo target to revalidate when that target changes, fixes <a href="http://plugins.jquery.com/node/11450">http://plugins.jquery.com/node/11450</a></li>
<li>Simplified select validation, delegating to jQuery&#8217;s val() method to get the select value; should fix <a href="http://plugins.jquery.com/node/11239">http://plugins.jquery.com/node/11239</a></li>
<li>Fixed default message for digits (<a href="http://plugins.jquery.com/node/9853">http://plugins.jquery.com/node/9853</a>)</li>
<li>Fixed issue with cached remote message (<a href="http://plugins.jquery.com/node/11029">http://plugins.jquery.com/node/11029</a> and <a href="http://plugins.jquery.com/node/9351">http://plugins.jquery.com/node/9351</a>)</li>
<li>Fixed a missing semicolon in additional-methods.js (<a href="http://plugins.jquery.com/node/9233">http://plugins.jquery.com/node/9233</a>)</li>
<li>Added automatic detection of substitution parameters in messages, removing the need to provide format functions (<a href="http://plugins.jquery.com/node/11195">http://plugins.jquery.com/node/11195</a>)</li>
<li>Fixed an issue with :filled/:blank somewhat caused by Sizzle (<a href="http://plugins.jquery.com/node/11144">http://plugins.jquery.com/node/11144</a>)</li>
<li>Added an integer method to additional-methods.js (<a href="http://plugins.jquery.com/node/9612">http://plugins.jquery.com/node/9612</a>)</li>
<li>Fixed errorsFor method where the for-attribute contains characters that need escaping to be valid inside a selector (<a href="http://plugins.jquery.com/node/9611">http://plugins.jquery.com/node/9611</a>)</li>
</ul>
<p>As usual, support is available via:</p>
<ul>
<li>Please post questions to the <a href="http://groups.google.com/group/jquery-en">jQuery discussion list</a>, putting &#8220;(validate)&#8221; into the subject of your post, making it easier to spot it and respond quickly. Keep your question short and succinct and provide code when possible; a testpage makes it much more likely that you get an useful answer in no time.</li>
<li>Please post bug reports and other contributions (enhancements, features, eg. new validation methods) to the <a href="http://plugins.jquery.com/project/issues/validate">plugins.jQuery.com bug tracker</a> (requires <a href="http://plugins.jquery.com/user/register">registration</a>).</li>
</ul>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/11/30/release-validation-plugin-1-6/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Undo/redo command stack in Java</title>
		<link>http://bassistance.de/2009/11/18/undoredo-command-stack-in-java/</link>
		<comments>http://bassistance.de/2009/11/18/undoredo-command-stack-in-java/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 13:48:21 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=582</guid>
		<description><![CDATA[Another fragment that turned out to be useless for the project, but may come handy in the future. A port to JavaScript should be easy enough, too:
import java.util.ArrayList;
import java.util.List;

public class CommandStack {

	/**
	 * Implement for each individual change that can occur in an editor.
	 *


	 * Both {@link #execute()} and {@link #undo()} should fire property [...]]]></description>
			<content:encoded><![CDATA[<p>Another fragment that turned out to be useless for the project, but may come handy in the future. A port to JavaScript should be easy enough, too:</p>
<pre><code class="java">import java.util.ArrayList;
import java.util.List;

public class CommandStack {

	/**
	 * Implement for each individual change that can occur in an editor.
	 *


	 * Both {@link #execute()} and {@link #undo()} should fire property change
	 * events for notifying the editor of an update.
	 */
	public static abstract class Command {

		private String name;

		public Command(String name) {
			this.name = name;
		}

		@Override
		public String toString() {
			return name;
		}

		/**
		 * Implements the actual change.
		 *


		 * Any state-saving for {@link #undo()}
		 * has to occur elsewhere, eg. in the constructor.
		 */
		public abstract void execute();

		/**
		 * Reverts any changes applied by {@link #execute()}.
		 */
		public abstract void undo();

	}

	private final List<Command> commands = new ArrayList<Command>();
	private int currentLocation = -1;
	private int saveLocation = currentLocation;

	public void add(Command command) {
		clearInFrontOfCurrent();
		command.execute();
		commands.add(command);
		currentLocation++;
	}

	public void undo() {
		commands.get(currentLocation).undo();
		currentLocation--;
	}

	public boolean undoEnabled() {
		return currentLocation >= 0;
	}

	public void redo() {
		currentLocation++;
		commands.get(currentLocation).execute();
	}

	public boolean redoEnabled() {
		return currentLocation < commands.size() - 1;
	}

	public boolean dirty() {
		return currentLocation != saveLocation;
	}

	private void clearInFrontOfCurrent() {
		while (currentLocation < commands.size() - 1) {
			commands.remove(currentLocation + 1);
		}
	}

	public void markSaveLocation() {
		saveLocation = currentLocation;
	}

	@Override
	public String toString() {
		return commands.toString();
	}

}</code></pre>
<p>And to illustrate the usage, the JUnit test:</p>
<pre><code class="java">import junit.framework.TestCase;

public class CommandStackTest extends TestCase {

	CommandStack stack = new CommandStack();

	private String name;
	private int age;

	class EditName extends Command {

		private String oldName = name;
		private String newName;

		public EditName(String newName) {
			super("Update name to " + newName);
			this.newName = newName;
		}

		public void execute() {
			name = newName;
		}

		public void undo() {
			name = oldName;
		}
	};

	class EditAge extends Command {

		private int oldAge = age;
		private int newAge;

		public EditAge(int newAge) {
			super("Update age to " + newAge);
			this.newAge = newAge;
		}

		public void execute() {
			age = newAge;
		}

		public void undo() {
			age = oldAge;
		}
	};

	public void test_basics() {
		assertNull(name);
		assertEquals(0, age);
		assertFalse(stack.dirty());
		assertFalse(stack.undoEnabled());
		assertFalse(stack.redoEnabled());

		stack.add(new EditName("Peter"));

		assertTrue(stack.dirty());
		assertEquals("Peter", name);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());

		stack.undo();

		assertNull(name);
		assertFalse(stack.undoEnabled());
		assertTrue(stack.redoEnabled());
		assertFalse(stack.dirty());

		stack.redo();

		assertTrue(stack.dirty());
		assertEquals("Peter", name);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());

		stack.markSaveLocation();

		assertFalse(stack.dirty());
		assertEquals("Peter", name);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());

		stack.add(new EditAge(10));

		assertTrue(stack.dirty());
		assertEquals(10, age);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());

		stack.undo();

		assertFalse(stack.dirty());
		assertEquals(0, age);
		assertTrue(stack.undoEnabled());
		assertTrue(stack.redoEnabled());

		stack.add(new EditName("Pan"));

		assertTrue(stack.dirty());
		assertEquals("Pan", name);
		assertEquals(0, age);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());

		stack.undo();
		stack.undo();

		assertTrue(stack.dirty());
		assertNull(name);
		assertEquals(0, age);
		assertFalse(stack.undoEnabled());
		assertTrue(stack.redoEnabled());

		stack.redo();
		stack.redo();

		assertTrue(stack.dirty());
		assertEquals("Pan", name);
		assertEquals(0, age);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
	}

}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/11/18/undoredo-command-stack-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse Dev: Custom Search Page</title>
		<link>http://bassistance.de/2009/11/17/eclipse-dev-custom-search-page/</link>
		<comments>http://bassistance.de/2009/11/17/eclipse-dev-custom-search-page/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 07:57:28 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=576</guid>
		<description><![CDATA[This is for the archive and due to lack of useful tutorials on writing custom search pages in your own Eclipse plugin. It turned out that the default text search is good enough for my purposes, so I&#8217;ll stick it here as a future reference.
To start, your Eclipse plugin needs to add org.eclipse.search as a [...]]]></description>
			<content:encoded><![CDATA[<p>This is for the archive and due to lack of useful tutorials on writing custom search pages in your own Eclipse plugin. It turned out that the default text search is good enough for my purposes, so I&#8217;ll stick it here as a future reference.</p>
<p>To start, your Eclipse plugin needs to add org.eclipse.search as a dependency, and, if you don&#8217;t have it already, org.eclipse.jface.text, too. With that, the Require-Bundle part of your MANIFEST.MF should look something like this:</p>
<pre><code>Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.ui.views,
org.eclipse.core.resources,
org.eclipse.ui.ide,
org.eclipse.ui.workbench.texteditor,
org.eclipse.text,
org.eclipse.ui.editors,
org.eclipse.search,
org.eclipse.jface.text</code></pre>
<p>Next, we&#8217;ll specify the extension for our custom search page, using the plugin.xml editor or just pasting and modifying this snippet:</p>
<pre><code class="html">&lt;extension point="org.eclipse.search.searchPages"&gt;
  &lt;page
    class="com.acm.your.product.CustomSearchPage"
    id="yourplugin.page1"
    label="Your Custom Search, rename this"&gt;
  &lt;/page&gt;
&lt;/extension&gt;</code></pre>
<p>And the actual implementation, providing a textfield as input, initialized with whatever text selection is currently active (thats where the org.eclipse.jface.text dependency comes from), and doing a text search across the full workspace:</p>
<pre><code class="java">package com.acm.your.product;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.search.ui.ISearchPage;
import org.eclipse.search.ui.ISearchPageContainer;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.TextSearchQueryProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class CustomSearchPage extends DialogPage implements ISearchPage {

	private String selected;
	private Text idText;

	public IdSearchPage() {
		super();
	}

	public IdSearchPage(String title) {
		super(title);
	}

	public boolean performAction() {
		if (idText.getText().length() == 0)
			return false;
		try {
			NewSearchUI.runQueryInBackground(TextSearchQueryProvider.getPreferred().createQuery(idText.getText()));
		} catch (IllegalArgumentException e) {
			throw new RuntimeException(e);
		} catch (CoreException e) {
			throw new RuntimeException(e);
		}
        return true;
	}

	public void setContainer(ISearchPageContainer container) {
		if (container.getSelection() instanceof TextSelection) {
			selected = ((TextSelection) container.getSelection()).getText();
		}
	}

	public void createControl(Composite parent) {
		GridLayout layout = new GridLayout(1, false);
		layout.horizontalSpacing = 5;
		layout.verticalSpacing = 5;
		parent.setLayout(layout);
		new Label(parent, 0).setText("Containing text:");
		idText = new Text(parent, SWT.BORDER);
		idText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		if (selected != null) {
			idText.setText(selected);
			idText.setSelection(0, selected.length());
		}
		setControl(parent);
	}

	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		idText.setFocus();
	}

}</code></pre>
<p>You can also restrict the files to search by creating a list first, and pass that to the search provider:</p>
<pre><code class="java">package com.acm.your.product;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.search.ui.ISearchPage;
import org.eclipse.search.ui.ISearchPageContainer;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.TextSearchQueryProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class CustomSearchPage2 extends DialogPage implements ISearchPage {

	private String selected;
	private Text idText;

	public IdSearchPage() {
		super();
	}

	public IdSearchPage(String title) {
		super(title);
	}

	public boolean performAction() {
		if (idText.getText().length() == 0)
			return false;
		try {
			final List<IResource> files = new ArrayList<IResource>();
			ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceProxyVisitor() {
				public boolean visit(IResourceProxy proxy) throws CoreException {
					if (proxy.getType() == IResource.FILE) {
						IFile file = (IFile) proxy.requestResource();
			            if (file.getLocation().getFileExtension() != null &#038;&#038; file.getLocation().getFileExtension().matches("xml|html|js|css")) {
			            	files.add(file);
			            }
			         }
			         return true;
				}
			}, IResource.DEPTH_INFINITE);
			NewSearchUI.runQueryInBackground(TextSearchQueryProvider.getPreferred().createQuery(idText.getText(), files.toArray(new IResource[0])));
		} catch (IllegalArgumentException e) {
			throw new RuntimeException(e);
		} catch (CoreException e) {
			throw new RuntimeException(e);
		}
        return true;
	}

	public void setContainer(ISearchPageContainer container) {
		if (container.getSelection() instanceof TextSelection) {
			selected = ((TextSelection) container.getSelection()).getText();
		}
	}

	public void createControl(Composite parent) {
		GridLayout layout = new GridLayout(1, false);
		layout.horizontalSpacing = 5;
		layout.verticalSpacing = 5;
		parent.setLayout(layout);
		new Label(parent, 0).setText("Containing text:");
		idText = new Text(parent, SWT.BORDER);
		idText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		if (selected != null) {
			idText.setText(selected);
			idText.setSelection(0, selected.length());
		}
		setControl(parent);
	}

	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		idText.setFocus();
	}

}</code></pre>
<p>This in itself doesn&#8217;t yet provide a lot of value, but if you actually need to build a custom search, its a good start.</p>
<p>Roughly based on <a href="http://wiki.eclipse.org/FAQ_How_do_I_write_a_Search_dialog%3F">this sort-of tutorial on the Eclipse wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/11/17/eclipse-dev-custom-search-page/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Doener Grenade</title>
		<link>http://bassistance.de/2009/09/03/doener-grenade/</link>
		<comments>http://bassistance.de/2009/09/03/doener-grenade/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 21:50:17 +0000</pubDate>
		<dc:creator>Jörn</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://bassistance.de/?p=572</guid>
		<description><![CDATA[Crawling some old backups, I found this:

Can you guess what it is? Well, along other files, there&#8217;s also a readme:
Author:    [BIA]_Enchos (TNT)
Email:  Enchos@gmx.net
HE DOENER
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-
Built to replace the HE grenade in Counter-Strike Halflife.
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-
This pack Include:
&#8212;
New Hud Sprites
All new models, v_, p_, and w_
Completly new skins
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-
Installation: Just extract the files to your cstrike-folder.
Be sure that the given [...]]]></description>
			<content:encoded><![CDATA[<p>Crawling some old backups, I found this:</p>
<p><img class="alignnone size-full wp-image-573" title="doener" src="http://bassistance.de/wp-content/doener.jpg" alt="doener" width="376" height="221" /></p>
<p>Can you guess what it is? Well, along other files, there&#8217;s also a readme:</p>
<blockquote><p>Author:    [BIA]_Enchos (TNT)<br />
Email:  Enchos@gmx.net</p>
<p>HE DOENER<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Built to replace the HE grenade in Counter-Strike Halflife.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>This pack Include:<br />
&#8212;<br />
New Hud Sprites<br />
All new models, v_, p_, and w_<br />
Completly new skins<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Installation: Just extract the files to your cstrike-folder.<br />
Be sure that the given pathes are used!<br />
(MDL-files in the models-folder and SPR-files in sprites-folder)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This is a replacement for the HE Grenade, but you can also you<br />
it as a flashbang. Make a copy of the 3 mdl´s and rename them to:<br />
p_flashbang.mdl<br />
v_flashbang.mdl<br />
w_flashbang.mdl<br />
&#8212;<br />
If you don´t want to use the new explosion-sprites, just delete<br />
eexplo.spr, fexplo1.spr and fexplo.spr! <img src='http://bassistance.de/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
<strong>Note:<br />
The &#8220;DOENER&#8221; is a kind of burger, but in combination with<br />
&#8220;TOMATO KETCHUP&#8221; it makes &#8220;BOOM&#8221;. Hurt your enemies<br />
around the corner and they will hate you <img src='http://bassistance.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Shoot through the<br />
corner and they will kill you .-|</strong><br />
&#8212;<br />
Still to do:<br />
I also wanted to make new sounds, but this is not as easy as I thought.<br />
If anybody knows how to do it, please mail me (Enchos@gmx.net).<br />
&lt;-&gt;<br />
Have a LOT of fun!!!<br />
&lt;-&gt;<br />
Suggestions, ideas, anything at all is welcome. Just e-mail me.<br />
&#8212;<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
&#8212;<br />
Be careful with hostages, they are allergic against doener´s.<br />
What? Your enemies too?!?</p></blockquote>
<p>The highlighted section &#8220;explains&#8221; the purpose of the tomato ketchup&#8230; so yeah, what was I thinking when creating that? I need to figure out how to show you the custom animation; the ketchup was actually poured over the undefined thing in the left hand! Also look at the awesome custom hand-texture&#8230;</p>
<p>Looking at the <a href="http://www.4players.de/cs.php/download_list/-/cs1.6/Waffen_Skins/HE%20Grenades/-/-/-/1/index.html">custom grenade models of a random Counterstrike site</a> &#8211; this one is still way cooler then those!</p>
]]></content:encoded>
			<wfw:commentRss>http://bassistance.de/2009/09/03/doener-grenade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.441 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-21 04:05:57 -->
