JBoss Rich Faces SVN: r10975 - trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2008-10-30 06:04:25 -0400 (Thu, 30 Oct 2008)
New Revision: 10975
Added:
trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextLexer.java
trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParser.java
trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParserTokenTypes.java
Log:
Html to SeamText parser
Added: trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextLexer.java
===================================================================
--- trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextLexer.java (rev 0)
+++ trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextLexer.java 2008-10-30 10:04:25 UTC (rev 10975)
@@ -0,0 +1,808 @@
+// $ANTLR : "html-seamtext.g" -> "HtmlSeamTextLexer.java"$
+
+ package org.richfaces.antlr;
+
+import java.io.InputStream;
+import antlr.TokenStreamException;
+import antlr.TokenStreamIOException;
+import antlr.TokenStreamRecognitionException;
+import antlr.CharStreamException;
+import antlr.CharStreamIOException;
+import antlr.ANTLRException;
+import java.io.Reader;
+import java.util.Hashtable;
+import antlr.CharScanner;
+import antlr.InputBuffer;
+import antlr.ByteBuffer;
+import antlr.CharBuffer;
+import antlr.Token;
+import antlr.CommonToken;
+import antlr.RecognitionException;
+import antlr.NoViableAltForCharException;
+import antlr.MismatchedCharException;
+import antlr.TokenStream;
+import antlr.ANTLRHashString;
+import antlr.LexerSharedInputState;
+import antlr.collections.impl.BitSet;
+import antlr.SemanticException;
+
+public class HtmlSeamTextLexer extends antlr.CharScanner implements HtmlSeamTextParserTokenTypes, TokenStream
+ {
+public HtmlSeamTextLexer(InputStream in) {
+ this(new ByteBuffer(in));
+}
+public HtmlSeamTextLexer(Reader in) {
+ this(new CharBuffer(in));
+}
+public HtmlSeamTextLexer(InputBuffer ib) {
+ this(new LexerSharedInputState(ib));
+}
+public HtmlSeamTextLexer(LexerSharedInputState state) {
+ super(state);
+ caseSensitiveLiterals = true;
+ setCaseSensitive(true);
+ literals = new Hashtable();
+}
+
+public Token nextToken() throws TokenStreamException {
+ Token theRetToken=null;
+tryAgain:
+ for (;;) {
+ Token _token = null;
+ int _ttype = Token.INVALID_TYPE;
+ resetText();
+ try { // for char stream error handling
+ try { // for lexical error handling
+ switch ( LA(1)) {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9': case 'A': case 'B':
+ case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V':
+ case 'W': case 'X': case 'Y': case 'Z':
+ case 'a': case 'b': case 'c': case 'd':
+ case 'e': case 'f': case 'g': case 'h':
+ case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p':
+ case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ {
+ mALPHANUMERICWORD(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '!': case '$': case '%': case '(':
+ case ')': case ',': case '-': case '.':
+ case ':': case ';': case '?': case '@':
+ case '{': case '}':
+ {
+ mPUNCTUATION(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '=':
+ {
+ mEQ(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '+':
+ {
+ mPLUS(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '_':
+ {
+ mUNDERSCORE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '*':
+ {
+ mSTAR(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '/':
+ {
+ mSLASH(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '\\':
+ {
+ mESCAPE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '|':
+ {
+ mBAR(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '`':
+ {
+ mBACKTICK(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '~':
+ {
+ mTWIDDLE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '"':
+ {
+ mDOUBLEQUOTE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '\'':
+ {
+ mSINGLEQUOTE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '[':
+ {
+ mOPEN(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case ']':
+ {
+ mCLOSE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '#':
+ {
+ mHASH(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '^':
+ {
+ mHAT(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '>':
+ {
+ mGT(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '<':
+ {
+ mLT(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '\t': case ' ':
+ {
+ mSPACE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '\n': case '\r':
+ {
+ mNEWLINE(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ case '\uffff':
+ {
+ mEOF(true);
+ theRetToken=_returnToken;
+ break;
+ }
+ default:
+ if ((LA(1)=='&') && (LA(2)=='l')) {
+ mESCAPED_LT(true);
+ theRetToken=_returnToken;
+ }
+ else if ((LA(1)=='&') && (LA(2)=='g')) {
+ mESCAPED_GT(true);
+ theRetToken=_returnToken;
+ }
+ else if ((LA(1)=='&') && (LA(2)=='a')) {
+ mESCAPED_AMP(true);
+ theRetToken=_returnToken;
+ }
+ else if ((LA(1)=='&') && (LA(2)=='q')) {
+ mESCAPED_QOUT(true);
+ theRetToken=_returnToken;
+ }
+ else if ((_tokenSet_0.member(LA(1)))) {
+ mUNICODEWORD(true);
+ theRetToken=_returnToken;
+ }
+ else if ((LA(1)=='&') && (true)) {
+ mAMPERSAND(true);
+ theRetToken=_returnToken;
+ }
+ else {
+ if (LA(1)==EOF_CHAR) {uponEOF(); _returnToken = makeToken(Token.EOF_TYPE);}
+ else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());}
+ }
+ }
+ if ( _returnToken==null ) continue tryAgain; // found SKIP token
+ _ttype = _returnToken.getType();
+ _ttype = testLiteralsTable(_ttype);
+ _returnToken.setType(_ttype);
+ return _returnToken;
+ }
+ catch (RecognitionException e) {
+ throw new TokenStreamRecognitionException(e);
+ }
+ }
+ catch (CharStreamException cse) {
+ if ( cse instanceof CharStreamIOException ) {
+ throw new TokenStreamIOException(((CharStreamIOException)cse).io);
+ }
+ else {
+ throw new TokenStreamException(cse.getMessage());
+ }
+ }
+ }
+}
+
+ public final void mALPHANUMERICWORD(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = ALPHANUMERICWORD;
+ int _saveIndex;
+
+ {
+ int _cnt430=0;
+ _loop430:
+ do {
+ switch ( LA(1)) {
+ case 'a': case 'b': case 'c': case 'd':
+ case 'e': case 'f': case 'g': case 'h':
+ case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p':
+ case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ {
+ matchRange('a','z');
+ break;
+ }
+ case 'A': case 'B': case 'C': case 'D':
+ case 'E': case 'F': case 'G': case 'H':
+ case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P':
+ case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ {
+ matchRange('A','Z');
+ break;
+ }
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ {
+ matchRange('0','9');
+ break;
+ }
+ default:
+ {
+ if ( _cnt430>=1 ) { break _loop430; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());}
+ }
+ }
+ _cnt430++;
+ } while (true);
+ }
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mUNICODEWORD(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = UNICODEWORD;
+ int _saveIndex;
+
+ {
+ int _cnt433=0;
+ _loop433:
+ do {
+ if (((LA(1) >= '\u00a0' && LA(1) <= '\u00ff'))) {
+ matchRange('\u00a0','\u00ff');
+ }
+ else if (((LA(1) >= '\u0100' && LA(1) <= '\u017f'))) {
+ matchRange('\u0100','\u017f');
+ }
+ else if (((LA(1) >= '\u0180' && LA(1) <= '\u024f'))) {
+ matchRange('\u0180','\u024f');
+ }
+ else if (((LA(1) >= '\u0250' && LA(1) <= '\ufaff'))) {
+ matchRange('\u0250','\ufaff');
+ }
+ else if (((LA(1) >= '\uff00' && LA(1) <= '\uffef'))) {
+ matchRange('\uff00','\uffef');
+ }
+ else {
+ if ( _cnt433>=1 ) { break _loop433; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());}
+ }
+
+ _cnt433++;
+ } while (true);
+ }
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mPUNCTUATION(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = PUNCTUATION;
+ int _saveIndex;
+
+ switch ( LA(1)) {
+ case '-':
+ {
+ match('-');
+ break;
+ }
+ case ';':
+ {
+ match(';');
+ break;
+ }
+ case ':':
+ {
+ match(':');
+ break;
+ }
+ case '(':
+ {
+ match('(');
+ break;
+ }
+ case ')':
+ {
+ match(')');
+ break;
+ }
+ case '{':
+ {
+ match('{');
+ break;
+ }
+ case '}':
+ {
+ match('}');
+ break;
+ }
+ case '?':
+ {
+ match('?');
+ break;
+ }
+ case '!':
+ {
+ match('!');
+ break;
+ }
+ case '@':
+ {
+ match('@');
+ break;
+ }
+ case '%':
+ {
+ match('%');
+ break;
+ }
+ case '.':
+ {
+ match('.');
+ break;
+ }
+ case ',':
+ {
+ match(',');
+ break;
+ }
+ case '$':
+ {
+ match('$');
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());
+ }
+ }
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mEQ(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = EQ;
+ int _saveIndex;
+
+ match('=');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mPLUS(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = PLUS;
+ int _saveIndex;
+
+ match('+');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mUNDERSCORE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = UNDERSCORE;
+ int _saveIndex;
+
+ match('_');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mSTAR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = STAR;
+ int _saveIndex;
+
+ match('*');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mSLASH(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = SLASH;
+ int _saveIndex;
+
+ match('/');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mESCAPE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = ESCAPE;
+ int _saveIndex;
+
+ match('\\');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mBAR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = BAR;
+ int _saveIndex;
+
+ match('|');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mBACKTICK(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = BACKTICK;
+ int _saveIndex;
+
+ match('`');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mTWIDDLE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = TWIDDLE;
+ int _saveIndex;
+
+ match('~');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mDOUBLEQUOTE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = DOUBLEQUOTE;
+ int _saveIndex;
+
+ match('"');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mSINGLEQUOTE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = SINGLEQUOTE;
+ int _saveIndex;
+
+ match('\'');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mOPEN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = OPEN;
+ int _saveIndex;
+
+ match('[');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mCLOSE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = CLOSE;
+ int _saveIndex;
+
+ match(']');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mHASH(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = HASH;
+ int _saveIndex;
+
+ match('#');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mHAT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = HAT;
+ int _saveIndex;
+
+ match('^');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mGT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = GT;
+ int _saveIndex;
+
+ match('>');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mLT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = LT;
+ int _saveIndex;
+
+ match('<');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mAMPERSAND(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = AMPERSAND;
+ int _saveIndex;
+
+ match('&');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mSPACE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = SPACE;
+ int _saveIndex;
+
+ {
+ int _cnt455=0;
+ _loop455:
+ do {
+ switch ( LA(1)) {
+ case ' ':
+ {
+ match(' ');
+ break;
+ }
+ case '\t':
+ {
+ match('\t');
+ break;
+ }
+ default:
+ {
+ if ( _cnt455>=1 ) { break _loop455; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());}
+ }
+ }
+ _cnt455++;
+ } while (true);
+ }
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mNEWLINE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = NEWLINE;
+ int _saveIndex;
+
+ if ((LA(1)=='\r') && (LA(2)=='\n')) {
+ match("\r\n");
+ }
+ else if ((LA(1)=='\r') && (true)) {
+ match('\r');
+ }
+ else if ((LA(1)=='\n')) {
+ match('\n');
+ }
+ else {
+ throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());
+ }
+
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mEOF(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = Token.EOF_TYPE;
+ int _saveIndex;
+
+ match('\uFFFF');
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mESCAPED_LT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = ESCAPED_LT;
+ int _saveIndex;
+
+ match("<");
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mESCAPED_GT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = ESCAPED_GT;
+ int _saveIndex;
+
+ match(">");
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mESCAPED_AMP(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = ESCAPED_AMP;
+ int _saveIndex;
+
+ match("&");
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+ public final void mESCAPED_QOUT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException {
+ int _ttype; Token _token=null; int _begin=text.length();
+ _ttype = ESCAPED_QOUT;
+ int _saveIndex;
+
+ match(""");
+ if ( _createToken && _token==null && _ttype!=Token.SKIP ) {
+ _token = makeToken(_ttype);
+ _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin));
+ }
+ _returnToken = _token;
+ }
+
+
+ private static final long[] mk_tokenSet_0() {
+ long[] data = new long[4084];
+ data[2]=-4294967296L;
+ for (int i = 3; i<=1003; i++) { data[i]=-1L; }
+ for (int i = 1020; i<=1022; i++) { data[i]=-1L; }
+ data[1023]=281474976710655L;
+ return data;
+ }
+ public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
+
+ }
Added: trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParser.java
===================================================================
--- trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParser.java (rev 0)
+++ trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParser.java 2008-10-30 10:04:25 UTC (rev 10975)
@@ -0,0 +1,1581 @@
+// $ANTLR : "html-seamtext.g" -> "HtmlSeamTextParser.java"$
+
+ package org.richfaces.antlr;
+
+import antlr.TokenBuffer;
+import antlr.TokenStreamException;
+import antlr.TokenStreamIOException;
+import antlr.ANTLRException;
+import antlr.LLkParser;
+import antlr.Token;
+import antlr.TokenStream;
+import antlr.RecognitionException;
+import antlr.NoViableAltException;
+import antlr.MismatchedTokenException;
+import antlr.SemanticException;
+import antlr.ParserSharedInputState;
+import antlr.collections.impl.BitSet;
+
+public class HtmlSeamTextParser extends antlr.LLkParser implements HtmlSeamTextParserTokenTypes
+ {
+
+ public class HtmlRecognitionException extends RecognitionException {
+ Token openingElement;
+ RecognitionException wrappedException;
+
+ public HtmlRecognitionException(Token openingElement, RecognitionException wrappedException) {
+ this.openingElement = openingElement;
+ this.wrappedException = wrappedException;
+ }
+
+ public Token getOpeningElement() {
+ return openingElement;
+ }
+
+ public String getMessage() {
+ return wrappedException.getMessage();
+ }
+
+ public Throwable getCause() {
+ return wrappedException;
+ }
+ }
+
+
+ public interface Sanitizer {
+
+ public void validateLinkTagURI(Token element, String uri) throws SemanticException;
+ public void validateHtmlElement(Token element) throws SemanticException;
+ public void validateHtmlAttribute(Token element, Token attribute) throws SemanticException;
+ public void validateHtmlAttributeValue(Token element, Token attribute, String attributeValue) throws SemanticException;
+ public void escapeSeamTextToken(Token element);
+ public String getInvalidURIMessage(String uri);
+ public String getInvalidElementMessage(String elementName);
+ public String getInvalidAttributeMessage(String elementName, String attributeName);
+ public String getInvalidAttributeValueMessage(String elementName, String attributeName, String value);
+
+ }
+
+ public static class DefaultSanitizer implements HtmlSeamTextParser.Sanitizer {
+
+ protected java.util.Set<String> attributesWhoseValueIsAURI = new java.util.HashSet(java.util.Arrays.asList(
+ "action", "cite", "href", "longdesc", "src", "xlink:href", "xml:base"
+ ));
+
+
+ protected java.util.Set<String> uriSchemes = new java.util.HashSet(java.util.Arrays.asList(
+ "afs", "aim", "callto", "ed2k", "feed", "ftp", "gopher", "http", "https",
+ "irc", "mailto", "news", "nntp", "rsync", "rtsp", "sftp", "ssh", "tag",
+ "tel", "telnet", "urn", "webcal", "wtai", "xmpp"
+ ));
+
+ protected java.util.Set<String> acceptableElements = new java.util.HashSet(java.util.Arrays.asList(
+ "a", "abbr", "acronym", "address", "area", "b", "bdo", "big", "blockquote",
+ "br", "button", "caption", "center", "cite", "code", "col", "colgroup", "dd",
+ "del", "dfn", "dir", "div", "dl", "dt", "em", "fieldset", "font", "form",
+ "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "input", "ins", "kbd",
+ "label", "legend", "li", "map", "menu", "ol", "optgroup", "option", "p",
+ "pre", "q", "s", "samp", "select", "small", "span", "strike", "strong",
+ "sub", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead",
+ "tr", "tt", "u", "ul", "var", "wbr"
+ ));
+
+ protected java.util.Set<String> mathmlElements = new java.util.HashSet(java.util.Arrays.asList(
+ "maction", "math", "merror", "mfrac", "mi", "mmultiscripts", "mn", "mo",
+ "mover", "mpadded", "mphantom", "mprescripts", "mroot", "mrow", "mspace",
+ "msqrt", "mstyle", "msub", "msubsup", "msup", "mtable", "mtd", "mtext",
+ "mtr", "munder", "munderover", "none"
+ ));
+
+ protected java.util.Set<String> svgElements = new java.util.HashSet(java.util.Arrays.asList(
+ "a", "animate", "animateColor", "animateMotion", "animateTransform",
+ "circle", "defs", "desc", "ellipse", "font-face", "font-face-name",
+ "font-face-src", "g", "glyph", "hkern", "image", "line", "linearGradient",
+ "marker", "metadata", "missing-glyph", "mpath", "path", "polygon",
+ "polyline", "radialGradient", "rect", "set", "stop", "svg", "switch", "text",
+ "title", "tspan", "use"
+ ));
+
+ protected java.util.Set<String> acceptableAttributes = new java.util.HashSet(java.util.Arrays.asList(
+ "abbr", "accept", "accept-charset", "accesskey", "action", "align", "alt",
+ "axis", "border", "cellpadding", "cellspacing", "char", "charoff", "charset",
+ "checked", "cite", "class", "clear", "color", "cols", "colspan", "compact",
+ "coords", "datetime", "dir", "disabled", "enctype", "for", "frame",
+ "headers", "height", "href", "hreflang", "hspace", "id", "ismap", "label",
+ "lang", "longdesc", "maxlength", "media", "method", "multiple", "name",
+ "nohref", "noshade", "nowrap", "prompt", "readonly", "rel", "rev", "rows",
+ "rowspan", "rules", "scope", "selected", "shape", "size", "span", "src",
+ "start", "style", "summary", "tabindex", "target", "title", "type", "usemap",
+ "valign", "value", "vspace", "width", "xml:lang"
+ ));
+
+ protected java.util.Set<String> mathmlAttributes = new java.util.HashSet(java.util.Arrays.asList(
+ "actiontype", "align", "columnalign", "columnalign", "columnalign",
+ "columnlines", "columnspacing", "columnspan", "depth", "display",
+ "displaystyle", "equalcolumns", "equalrows", "fence", "fontstyle",
+ "fontweight", "frame", "height", "linethickness", "lspace", "mathbackground",
+ "mathcolor", "mathvariant", "mathvariant", "maxsize", "minsize", "other",
+ "rowalign", "rowalign", "rowalign", "rowlines", "rowspacing", "rowspan",
+ "rspace", "scriptlevel", "selection", "separator", "stretchy", "width",
+ "width", "xlink:href", "xlink:show", "xlink:type", "xmlns", "xmlns:xlink"
+ ));
+
+
+ protected java.util.Set<String> svgAttributes = new java.util.HashSet(java.util.Arrays.asList(
+ "accent-height", "accumulate", "additive", "alphabetic", "arabic-form",
+ "ascent", "attributeName", "attributeType", "baseProfile", "bbox", "begin",
+ "by", "calcMode", "cap-height", "class", "color", "color-rendering",
+ "content", "cx", "cy", "d", "descent", "display", "dur", "dx", "dy", "end",
+ "fill", "fill-rule", "font-family", "font-size", "font-stretch",
+ "font-style", "font-variant", "font-weight", "from", "fx", "fy", "g1", "g2",
+ "glyph-name", "gradientUnits", "hanging", "height", "horiz-adv-x",
+ "horiz-origin-x", "id", "ideographic", "k", "keyPoints", "keySplines",
+ "keyTimes", "lang", "marker-end", "marker-mid", "marker-start",
+ "markerHeight", "markerUnits", "markerWidth", "mathematical", "max", "min",
+ "name", "offset", "opacity", "orient", "origin", "overline-position",
+ "overline-thickness", "panose-1", "path", "pathLength", "points",
+ "preserveAspectRatio", "r", "refX", "refY", "repeatCount", "repeatDur",
+ "requiredExtensions", "requiredFeatures", "restart", "rotate", "rx", "ry",
+ "slope", "stemh", "stemv", "stop-color", "stop-opacity",
+ "strikethrough-position", "strikethrough-thickness", "stroke",
+ "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
+ "stroke-miterlimit", "stroke-opacity", "stroke-width", "systemLanguage",
+ "target", "text-anchor", "to", "transform", "type", "u1", "u2",
+ "underline-position", "underline-thickness", "unicode", "unicode-range",
+ "units-per-em", "values", "version", "viewBox", "visibility", "width",
+ "widths", "x", "x-height", "x1", "x2", "xlink:actuate", "xlink:arcrole",
+ "xlink:href", "xlink:role", "xlink:show", "xlink:title", "xlink:type",
+ "xml:base", "xml:lang", "xml:space", "xmlns", "xmlns:xlink", "y", "y1", "y2",
+ "zoomAndPan"
+ ));
+
+ public final java.util.regex.Pattern REGEX_VALID_CSS_VALUE = java.util.regex.Pattern.compile(
+ "^(#[0-9a-f]{3,6}|rgb\\(\\d{1,3}%?,\\d{1,3}%?,?\\d{1,3}%?\\)?|-?\\d{0,2}\\.?\\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\\))?)$"
+ );
+
+ public final java.util.regex.Pattern REGEX_VALID_CSS_STRING1 = java.util.regex.Pattern.compile(
+ "^([-:,;#%.\\sa-zA-Z0-9!]|\\w-\\w|'[\\s\\w]+'|\"[\\s\\w]+\"|\\([\\d,\\s]+\\))*$"
+ );
+
+ public final java.util.regex.Pattern REGEX_VALID_CSS_STRING2 = java.util.regex.Pattern.compile(
+ "^(\\s*[-\\w]+\\s*:\\s*[^:;]*(;|$))*$"
+ );
+
+
+ protected java.util.Set<String> styleProperties = new java.util.HashSet(java.util.Arrays.asList(
+ "azimuth",
+ "background", "background-attachment", "background-color", "background-image",
+ "background-position", "background-repeat",
+ "border", "border-bottom", "border-bottom-color", "border-bottom-style",
+ "border-bottom-width", "border-collapse", "border-color", "border-left",
+ "border-left-color", "border-left-style", "border-left-width", "border-right",
+ "border-right-color", "border-right-style", "border-right-width", "border-spacing",
+ "border-style", "border-top", "border-top-color", "border-top-style",
+ "border-top-width", "border-width",
+ "clear", "color",
+ "cursor", "direction", "display", "elevation", "float", "font",
+ "font-family", "font-size", "font-style", "font-variant", "font-weight",
+ "height", "letter-spacing", "line-height",
+ "margin", "margin-bottom", "margin-left", "margin-right", "margin-top",
+ "max-height", "max-width", "min-height", "min-width",
+ "overflow",
+ "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
+ "pause", "pause-after", "pause-before", "pitch",
+ "pitch-range", "richness", "speak", "speak-header", "speak-numeral",
+ "speak-punctuation", "speech-rate", "stress", "text-align",
+ "text-decoration", "text-indent", "unicode-bidi", "vertical-align",
+ "voice-family", "volume", "white-space", "width"
+ ));
+
+
+ protected java.util.Set<String> stylePropertiesValues = new java.util.HashSet(java.util.Arrays.asList(
+ "aqua", "auto", "baseline", "black", "block", "blue", "bold", "both", "bottom", "brown",
+ "center", "collapse", "dashed", "dotted", "fuchsia", "gray", "green",
+ "inherit", "italic", "left", "length", "lime", "maroon", "medium", "middle", "navy", "none", "normal",
+ "nowrap", "olive", "percentage", "pointer", "purple", "red", "right", "silver", "solid", "sub", "super",
+ "teal", "text-bottom", "text-top", "top", "transparent", "underline", "white", "yellow"
+ ));
+
+ protected java.util.Set<String> svgStyleProperties = new java.util.HashSet(java.util.Arrays.asList(
+ "fill", "fill-opacity", "fill-rule", "stroke", "stroke-linecap",
+ "stroke-linejoin", "stroke-opacity", "stroke-width"
+ ));
+
+
+ public void validateLinkTagURI(Token element, String uri) throws SemanticException {
+ if (!validateURI(uri)) {
+ throw createSemanticException("Invalid URI", element);
+ }
+ }
+
+ public void validateHtmlElement(Token element) throws SemanticException {
+ String elementName = element.getText().toLowerCase();
+ if (!acceptableElements.contains(elementName) &&
+ !svgElements.contains(elementName) &&
+ !mathmlElements.contains(elementName)) {
+ throw createSemanticException(getInvalidElementMessage(elementName), element);
+ }
+ }
+
+ public void validateHtmlAttribute(Token element, Token attribute) throws SemanticException {
+ String elementName = element.getText().toLowerCase();
+ String attributeName = attribute.getText().toLowerCase();
+ if (!acceptableAttributes.contains(attributeName) &&
+ !svgAttributes.contains(attributeName) &&
+ !mathmlAttributes.contains(attributeName)) {
+ throw createSemanticException(getInvalidAttributeMessage(elementName, attributeName), element);
+ }
+
+ }
+
+ public void validateHtmlAttributeValue(Token element, Token attribute, String attributeValue) throws SemanticException{
+
+ if (attributeValue == null || attributeValue.length() == 0) return;
+
+ String elementName = element.getText().toLowerCase();
+ String attributeName = attribute.getText().toLowerCase();
+
+ // Check element with attribute that has URI value (href, src, etc.)
+ if (attributesWhoseValueIsAURI.contains(attributeName) && !validateURI(attributeValue)) {
+ throw createSemanticException(getInvalidURIMessage(attributeValue), element);
+ }
+
+ // Check attribute value of style (CSS filtering)
+ if (attributeName.equals("style")) {
+ if (!REGEX_VALID_CSS_STRING1.matcher(attributeValue).matches() ||
+ !REGEX_VALID_CSS_STRING2.matcher(attributeValue).matches()) {
+ throw createSemanticException(
+ getInvalidAttributeValueMessage(elementName, attributeName, attributeValue),
+ element
+ );
+ }
+
+ String[] cssProperties = attributeValue.split(";");
+ for (String cssProperty : cssProperties) {
+ if (!cssProperty.contains(":")) {
+ throw createSemanticException(
+ getInvalidAttributeValueMessage(elementName, attributeName, attributeValue),
+ element
+ );
+ }
+ String[] property = cssProperty.split(":");
+ String propertyName = property[0].trim();
+ String propertyValue = property.length == 2 ? property[1].trim() : null;
+
+ // CSS property name
+ if (!styleProperties.contains(propertyName) &&
+ !svgStyleProperties.contains(propertyName)) {
+ throw createSemanticException(
+ getInvalidAttributeValueMessage(elementName, attributeName, attributeValue),
+ element
+ );
+ }
+
+ // CSS property value
+ if (propertyValue != null && !stylePropertiesValues.contains(propertyValue)) {
+ // Not in list, now check the regex
+ if (!REGEX_VALID_CSS_VALUE.matcher(propertyValue).matches()) {
+ throw createSemanticException(
+ getInvalidAttributeValueMessage(elementName, attributeName, attributeValue),
+ element
+ );
+ }
+ }
+ }
+ }
+
+
+ }
+
+ public String getInvalidURIMessage(String uri){
+ return "invalid URI";
+ }
+
+ public String getInvalidElementMessage(String elementName){
+ return "invalid element '" + elementName + "'";
+ }
+
+ public String getInvalidAttributeMessage(String elementName, String attributeName){
+ return "invalid attribute '" + attributeName + "' for element '" + elementName + "'";
+ }
+
+ public String getInvalidAttributeValueMessage(String elementName, String attributeName, String value){
+ return "invalid value of attribute '" + attributeName + "' for element '" + elementName + "'";
+ }
+
+ public void escapeSeamTextToken(Token element) {
+ }
+
+ protected boolean validateURI(String uri) {
+
+ // Relative URI starts with a slash
+ if (uri.startsWith("/")) return true;
+
+ java.net.URI parsedURI;
+ try {
+ parsedURI = new java.net.URI(uri);
+ } catch (java.net.URISyntaxException ex) {
+ return false;
+ }
+
+ if (!uriSchemes.contains(parsedURI.getScheme())) {
+ return false;
+ }
+ return true;
+ }
+
+ public SemanticException createSemanticException(String message, Token element) {
+ return new SemanticException(
+ message,
+ element.getFilename(), element.getLine(), element.getColumn()
+ );
+ }
+
+ }
+
+
+ private final String SEAMTEXT_MONOSPACE = "|";
+
+ private final String SEAMTEXT_TWIDDLE = "~";
+
+ private final String SEAMTEXT_HASH = "#";
+
+ private final String SEAMTEXT_HAT = "^";
+
+ private final String SEAMTEXT_PLUS = "+";
+
+ private final String SEAMTEXT_STAR = "*";
+
+ private final String SEAMTEXT_UNDERSCORE = "_";
+
+ private final String SEAMTEXT_EQ = "=";
+
+ private final String SEAMTEXT_BACKTICK = "`";
+
+ private final String SEAMTEXT_PARAGRAPH = "\n\n";
+
+ private final String SEAM_DOUBLEQUOTE = "\"";
+
+ private final String SEAM_OPEN = "[";
+
+ private final String SEAM_CLOSE = "]";
+
+ private final String SEAM_GT = ">";
+
+
+ protected java.util.Set<String> seamTextSymbols = new java.util.HashSet(java.util.Arrays.asList(
+ SEAMTEXT_MONOSPACE, SEAMTEXT_TWIDDLE, SEAMTEXT_HASH, SEAMTEXT_HAT, SEAMTEXT_PLUS, SEAMTEXT_STAR,
+ SEAMTEXT_UNDERSCORE, SEAMTEXT_EQ, SEAMTEXT_BACKTICK, SEAMTEXT_PARAGRAPH, SEAM_DOUBLEQUOTE, SEAM_OPEN,
+ SEAM_CLOSE, SEAM_GT
+ ));
+
+ protected java.util.Set<String> htmlSeamTextElements = new java.util.HashSet(java.util.Arrays.asList(
+ "del", "sup", "pre","p", "q" ,"h1" ,"h2" ,"h3" ,"h4" ,"ul" ,"ol" ,"li" ,"i" ,"tt" ,"u" ,"a"));
+
+ private Sanitizer sanitizer = new DefaultSanitizer();
+
+ private java.util.Stack<Token> htmlElementStack = new java.util.Stack<Token>();
+
+ private StringBuilder mainBuilder = new StringBuilder();
+
+ private StringBuilder linkValueCollector = new StringBuilder();
+
+ private String linkHolder;
+
+ private StringBuilder builder = mainBuilder;
+
+
+ public void setSanitizer(Sanitizer sanitizer) {
+ this.sanitizer = sanitizer;
+ }
+
+ public String toString() {
+ return builder.toString();
+ }
+
+ private void beginCapture() {
+ builder = new StringBuilder();
+ }
+
+ private String endCapture() {
+ String result = builder.toString();
+ builder = mainBuilder;
+ return result;
+ }
+
+ private void append(String... strings) {
+ for (String string: strings) builder.append(string);
+ }
+
+
+ public boolean isLink(Token token) {
+ String name = token.getText().toLowerCase();
+ return "a".equals(name);
+ }
+
+ private String createSeamTextLink(String link, String value) {
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+
+ if (value != null) {
+ builder.append(value.trim());
+ }
+
+ builder.append("=>");
+ builder.append(link);
+ builder.append("]");
+
+ return builder.toString();
+
+ }
+
+ public boolean isHeader(Token token) {
+ String name = token.getText().toLowerCase();
+ return ("h1".equals(name) || "h2".equals(name) || "h3".equals(name) || "h4".equals(name));
+ }
+
+ public String createSeamTextHeader(Token token) throws SemanticException {
+
+ String name = token.getText();
+ StringBuilder seamHeader = new StringBuilder();
+
+ if("h1".equals(name)) {
+ seamHeader.append("\n").append(SEAMTEXT_PLUS);
+ } else if("h2".equals(name)) {
+ seamHeader.append("\n").append(SEAMTEXT_PLUS).append(SEAMTEXT_PLUS);
+ } else if("h3".equals(name)) {
+ seamHeader.append("\n").append(SEAMTEXT_PLUS).append(SEAMTEXT_PLUS).append(SEAMTEXT_PLUS);
+ } else if("h4".equals(name)) {
+ seamHeader.append("\n").append(SEAMTEXT_PLUS).append(SEAMTEXT_PLUS).append(SEAMTEXT_PLUS).append(SEAMTEXT_PLUS);
+ }
+
+ return seamHeader.toString();
+ }
+
+ public boolean isList(Token token){
+ String name = token.getText();
+ return ("ul".equals(name) || "ol".equals(name));
+ }
+
+ public boolean isListItem(Token token) {
+ String name = token.getText().toLowerCase();
+ return "li".equals(name);
+ }
+
+ public String createSeamTextList(Token token, java.util.Stack <Token> htmlElementStack) throws SemanticException {
+ String seamText = null;
+
+ Token parent = htmlElementStack.peek();
+ String parentName = parent.getText().toLowerCase();
+ if(parentName.equals("ul")) {
+ seamText = SEAMTEXT_HASH;
+ } else if (parentName.equals("ol")){
+ seamText = SEAMTEXT_EQ;
+ } else {
+ String message = "<li> must follow <ol> or <ul> not <" + parent.getText() + ">";
+ throw new SemanticException( message, parent.getFilename(), parent.getLine(), parent.getColumn());
+ }
+
+ return seamText != null ? seamText : "";
+ }
+
+ // validate lists and headers'
+ public void validateNestedMarkup(Token name, java.util.Stack <Token> htmlElementStack) throws SemanticException {
+ if(!htmlElementStack.isEmpty()) {
+ for(Token token : htmlElementStack) {
+
+ if(token.getText().equals("h1") || token.getText().equals("h2") || token.getText().equals("h3")
+ || token.getText().equals("h4") || token.getText().equals("ol") || token.getText().equals("ul")) {
+ String message = "<" + token.getText() + "> contains nested <" + name.getText() + "> token";
+ throw new SemanticException( message, name.getFilename(), name.getLine(), name.getColumn());
+ }
+ }
+ }
+
+ }
+
+ public void validateHeaderMarkup(Token token, java.util.Stack <Token> htmlElementStack) throws TokenStreamException, SemanticException{
+ int EOF = 1;
+ int ALPHANUMERICWORD = 4;
+ int i = 0;
+ int type;
+
+ boolean containText = false;
+
+ Token element = htmlElementStack.peek();
+ String header = element.getText();
+
+ if (header.equals("h1") || header.equals("h2") || header.equals("h3") || header.equals("h4")) {
+ do {
+ i++;
+ type = LT(i).getType();
+ if (type == ALPHANUMERICWORD) {
+ containText = true;
+ break;
+ }
+
+ } while ( type != EOF);
+
+ if (!containText) {
+ String message = "You must have some text following a heading";
+ throw new SemanticException( message, element.getFilename(), element.getLine(), element.getColumn());
+ }
+ }
+
+ }
+
+ public String createSimpleSeamText(Token token) throws SemanticException{
+
+ String name = token.getText().toLowerCase();
+ StringBuilder seamText = new StringBuilder();
+
+ if("tt".equals(name)) {
+ seamText.append(SEAMTEXT_MONOSPACE);
+ } else if("del".equals(name)) {
+ seamText.append(SEAMTEXT_TWIDDLE);
+ } else if("i".equals(name)) {
+ seamText.append(SEAMTEXT_STAR);
+ } else if("sup".equals(name)) {
+ seamText.append(SEAMTEXT_HAT);
+ } else if("u".equals(name)) {
+ seamText.append(SEAMTEXT_UNDERSCORE);
+ } else if("pre".equals(name)) {
+ seamText.append(SEAMTEXT_BACKTICK);
+ } else if("p".equals(name)) {
+ seamText.append(SEAMTEXT_PARAGRAPH);
+ } else if("q".equals(name)) {
+ seamText.append(SEAM_DOUBLEQUOTE);
+ } else if("blockquote".equals(name)) {
+ seamText.append(SEAM_DOUBLEQUOTE);
+ }
+
+ return seamText.toString();
+
+ }
+
+ public boolean isSeamTextElement(Token element){
+ String name = element.getText().toLowerCase();
+ return htmlSeamTextElements.contains(name);
+ }
+
+
+ public String escapeSeamText(Token token, java.util.Stack <Token> parentHtmlTokens) throws TokenStreamException {
+
+ StringBuilder result = new StringBuilder();
+ String tokenName = token.getText();
+
+ if(parentHtmlTokens != null && !parentHtmlTokens.isEmpty()){
+ Token parentToken = parentHtmlTokens.peek();
+ String parentTokenName = parentToken.getText().toLowerCase();
+
+ if ("tt".equals(parentTokenName) || "pre".equals(parentTokenName)) {
+
+ if ("<".equals(tokenName)) {
+ result.append("<");
+ } else if("&".equals(tokenName)) {
+ result.append("&");
+ } else if (">".equals(tokenName)) {
+ result.append(">");
+ } else if(""".equals(tokenName)){
+ result.append("\"");
+ }else if(seamTextSymbols.contains(tokenName)) {
+ result.append(tokenName);
+ }
+ }
+ }
+ result = result.length() != 0 ? result : result.append("\\").append(tokenName);
+ return result.toString();
+ }
+
+
+
+
+protected HtmlSeamTextParser(TokenBuffer tokenBuf, int k) {
+ super(tokenBuf,k);
+ tokenNames = _tokenNames;
+}
+
+public HtmlSeamTextParser(TokenBuffer tokenBuf) {
+ this(tokenBuf,4);
+}
+
+protected HtmlSeamTextParser(TokenStream lexer, int k) {
+ super(lexer,k);
+ tokenNames = _tokenNames;
+}
+
+public HtmlSeamTextParser(TokenStream lexer) {
+ this(lexer,4);
+}
+
+public HtmlSeamTextParser(ParserSharedInputState state) {
+ super(state,4);
+ tokenNames = _tokenNames;
+}
+
+ public final void startRule() throws RecognitionException, TokenStreamException {
+
+
+ {
+ _loop388:
+ do {
+ if ((LA(1)==NEWLINE)) {
+ newline();
+ }
+ else {
+ break _loop388;
+ }
+
+ } while (true);
+ }
+ {
+ switch ( LA(1)) {
+ case ALPHANUMERICWORD:
+ case UNICODEWORD:
+ case DOUBLEQUOTE:
+ case ESCAPED_LT:
+ case ESCAPED_GT:
+ case ESCAPED_AMP:
+ case ESCAPED_QOUT:
+ case PUNCTUATION:
+ case SINGLEQUOTE:
+ case SLASH:
+ case STAR:
+ case BAR:
+ case HAT:
+ case PLUS:
+ case EQ:
+ case HASH:
+ case ESCAPE:
+ case TWIDDLE:
+ case OPEN:
+ case CLOSE:
+ case BACKTICK:
+ case GT:
+ case SPACE:
+ case LT:
+ {
+ text();
+ eof();
+ break;
+ }
+ case EOF:
+ {
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+ }
+
+ public final void newline() throws RecognitionException, TokenStreamException {
+
+ Token n = null;
+
+ n = LT(1);
+ match(NEWLINE);
+ append(n.getText());
+ }
+
+ public final void text() throws RecognitionException, TokenStreamException {
+
+
+ {
+ int _cnt395=0;
+ _loop395:
+ do {
+ if ((_tokenSet_0.member(LA(1)))) {
+ {
+ switch ( LA(1)) {
+ case STAR:
+ case BAR:
+ case HAT:
+ case PLUS:
+ case EQ:
+ case HASH:
+ case ESCAPE:
+ case TWIDDLE:
+ case OPEN:
+ case CLOSE:
+ case BACKTICK:
+ case GT:
+ {
+ seamCharacters();
+ break;
+ }
+ case ALPHANUMERICWORD:
+ case UNICODEWORD:
+ case PUNCTUATION:
+ case SINGLEQUOTE:
+ case SLASH:
+ case SPACE:
+ {
+ plain();
+ break;
+ }
+ case LT:
+ {
+ html();
+ break;
+ }
+ case DOUBLEQUOTE:
+ case ESCAPED_LT:
+ case ESCAPED_GT:
+ case ESCAPED_AMP:
+ case ESCAPED_QOUT:
+ {
+ htmlSpecialChars();
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+ {
+ _loop394:
+ do {
+ if ((LA(1)==NEWLINE)) {
+ newline();
+ }
+ else {
+ break _loop394;
+ }
+
+ } while (true);
+ }
+ }
+ else {
+ if ( _cnt395>=1 ) { break _loop395; } else {throw new NoViableAltException(LT(1), getFilename());}
+ }
+
+ _cnt395++;
+ } while (true);
+ }
+ }
+
+ public final void eof() throws RecognitionException, TokenStreamException {
+
+
+ match(Token.EOF_TYPE);
+ }
+
+ public final void seamCharacters() throws RecognitionException, TokenStreamException {
+
+ Token hat = null;
+ Token hash = null;
+ Token open = null;
+ Token close = null;
+ Token twiddle = null;
+ Token bar = null;
+ Token eq = null;
+ Token plus = null;
+ Token backtick = null;
+ Token st = null;
+ Token e = null;
+ Token gt = null;
+
+ switch ( LA(1)) {
+ case HAT:
+ {
+ hat = LT(1);
+ match(HAT);
+ append(escapeSeamText(hat, htmlElementStack));
+ break;
+ }
+ case HASH:
+ {
+ hash = LT(1);
+ match(HASH);
+ append(escapeSeamText(hash, htmlElementStack));
+ break;
+ }
+ case OPEN:
+ {
+ open = LT(1);
+ match(OPEN);
+ append(escapeSeamText(open, htmlElementStack)) ;
+ break;
+ }
+ case CLOSE:
+ {
+ close = LT(1);
+ match(CLOSE);
+ append(escapeSeamText(close, htmlElementStack));
+ break;
+ }
+ case TWIDDLE:
+ {
+ twiddle = LT(1);
+ match(TWIDDLE);
+ append(escapeSeamText(twiddle, htmlElementStack));
+ break;
+ }
+ case BAR:
+ {
+ bar = LT(1);
+ match(BAR);
+ append(escapeSeamText(bar, htmlElementStack));
+ break;
+ }
+ case EQ:
+ {
+ eq = LT(1);
+ match(EQ);
+ append(escapeSeamText(eq, htmlElementStack));
+ break;
+ }
+ case PLUS:
+ {
+ plus = LT(1);
+ match(PLUS);
+ append(escapeSeamText(plus, htmlElementStack));
+ break;
+ }
+ case BACKTICK:
+ {
+ backtick = LT(1);
+ match(BACKTICK);
+ append(escapeSeamText(backtick, htmlElementStack));
+ break;
+ }
+ case STAR:
+ {
+ st = LT(1);
+ match(STAR);
+ append(escapeSeamText(st, htmlElementStack));
+ break;
+ }
+ case ESCAPE:
+ {
+ e = LT(1);
+ match(ESCAPE);
+ append(escapeSeamText(e, htmlElementStack));
+ break;
+ }
+ case GT:
+ {
+ gt = LT(1);
+ match(GT);
+ append(escapeSeamText(gt, htmlElementStack));
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+
+ public final void plain() throws RecognitionException, TokenStreamException {
+
+
+ {
+ switch ( LA(1)) {
+ case ALPHANUMERICWORD:
+ case UNICODEWORD:
+ {
+ word();
+ break;
+ }
+ case PUNCTUATION:
+ case SINGLEQUOTE:
+ case SLASH:
+ {
+ punctuation();
+ break;
+ }
+ case SPACE:
+ {
+ space();
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+ }
+
+ public final void html() throws RecognitionException, TokenStreamException {
+
+
+ openTag();
+ {
+ _loop407:
+ do {
+ if ((LA(1)==SPACE) && (LA(2)==SLASH||LA(2)==GT||LA(2)==SPACE)) {
+ space();
+ }
+ else if ((LA(1)==SPACE) && (LA(2)==ALPHANUMERICWORD)) {
+ space();
+ attribute();
+ }
+ else {
+ break _loop407;
+ }
+
+ } while (true);
+ }
+ {
+ switch ( LA(1)) {
+ case GT:
+ {
+ {
+ beforeBody();
+ body();
+ closeTagWithBody();
+ }
+ break;
+ }
+ case SLASH:
+ {
+ closeTagWithNoBody();
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+ }
+
+ public final void htmlSpecialChars() throws RecognitionException, TokenStreamException {
+
+ Token lt = null;
+ Token gt = null;
+ Token amp = null;
+ Token qout = null;
+
+ switch ( LA(1)) {
+ case DOUBLEQUOTE:
+ {
+ match(DOUBLEQUOTE);
+ append("\"");
+ break;
+ }
+ case ESCAPED_LT:
+ {
+ lt = LT(1);
+ match(ESCAPED_LT);
+ append(escapeSeamText(lt, htmlElementStack));
+ break;
+ }
+ case ESCAPED_GT:
+ {
+ gt = LT(1);
+ match(ESCAPED_GT);
+ append(escapeSeamText(gt, htmlElementStack));
+ break;
+ }
+ case ESCAPED_AMP:
+ {
+ amp = LT(1);
+ match(ESCAPED_AMP);
+ append(escapeSeamText(amp, htmlElementStack));
+ break;
+ }
+ case ESCAPED_QOUT:
+ {
+ qout = LT(1);
+ match(ESCAPED_QOUT);
+ append(escapeSeamText(qout, htmlElementStack));
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+
+ public final void word() throws RecognitionException, TokenStreamException {
+
+ Token an = null;
+ Token uc = null;
+
+ switch ( LA(1)) {
+ case ALPHANUMERICWORD:
+ {
+ an = LT(1);
+ match(ALPHANUMERICWORD);
+ append( an.getText() );
+ break;
+ }
+ case UNICODEWORD:
+ {
+ uc = LT(1);
+ match(UNICODEWORD);
+ append( uc.getText() );
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+
+ public final void punctuation() throws RecognitionException, TokenStreamException {
+
+ Token p = null;
+ Token sq = null;
+ Token s = null;
+
+ switch ( LA(1)) {
+ case PUNCTUATION:
+ {
+ p = LT(1);
+ match(PUNCTUATION);
+ append( p.getText() );
+ break;
+ }
+ case SINGLEQUOTE:
+ {
+ sq = LT(1);
+ match(SINGLEQUOTE);
+ append( sq.getText() );
+ break;
+ }
+ case SLASH:
+ {
+ s = LT(1);
+ match(SLASH);
+ append( s.getText() );
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+
+ public final void specialChars() throws RecognitionException, TokenStreamException {
+
+ Token st = null;
+ Token b = null;
+ Token h = null;
+ Token p = null;
+ Token eq = null;
+ Token hh = null;
+ Token e = null;
+ Token t = null;
+ Token u = null;
+
+ switch ( LA(1)) {
+ case STAR:
+ {
+ st = LT(1);
+ match(STAR);
+ append( st.getText() );
+ break;
+ }
+ case BAR:
+ {
+ b = LT(1);
+ match(BAR);
+ append( b.getText() );
+ break;
+ }
+ case HAT:
+ {
+ h = LT(1);
+ match(HAT);
+ append( h.getText() );
+ break;
+ }
+ case PLUS:
+ {
+ p = LT(1);
+ match(PLUS);
+ append( p.getText() );
+ break;
+ }
+ case EQ:
+ {
+ eq = LT(1);
+ match(EQ);
+ append( eq.getText() );
+ break;
+ }
+ case HASH:
+ {
+ hh = LT(1);
+ match(HASH);
+ append( hh.getText() );
+ break;
+ }
+ case ESCAPE:
+ {
+ e = LT(1);
+ match(ESCAPE);
+ append( e.getText() );
+ break;
+ }
+ case TWIDDLE:
+ {
+ t = LT(1);
+ match(TWIDDLE);
+ append( t.getText() );
+ break;
+ }
+ case UNDERSCORE:
+ {
+ u = LT(1);
+ match(UNDERSCORE);
+ append( u.getText() );
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+
+ public final void space() throws RecognitionException, TokenStreamException {
+
+ Token s = null;
+
+ s = LT(1);
+ match(SPACE);
+
+
+ if(!htmlElementStack.isEmpty()) {
+ String tokenName = htmlElementStack.peek().getText();
+ if(!("ul".equals(tokenName) || "ol".equals(tokenName))) {
+ append(s.getText());
+ }
+
+ } else {
+ append(s.getText());
+ }
+
+
+ }
+
+ public final void newlineOrEof() throws RecognitionException, TokenStreamException {
+
+
+ switch ( LA(1)) {
+ case NEWLINE:
+ {
+ newline();
+ break;
+ }
+ case EOF:
+ {
+ match(Token.EOF_TYPE);
+ break;
+ }
+ default:
+ {
+ throw new NoViableAltException(LT(1), getFilename());
+ }
+ }
+ }
+
+ public final void openTag() throws RecognitionException, TokenStreamException {
+
+ Token name = null;
+
+ try { // for error handling
+ match(LT);
+ name = LT(1);
+ match(ALPHANUMERICWORD);
+
+
+
+ sanitizer.validateHtmlElement(name);
+
+ if (isSeamTextElement(name)) {
+ if (isList(name)) {
+ validateNestedMarkup(name, htmlElementStack);
+ } else if (isListItem(name)) {
+ append(createSeamTextList(name,htmlElementStack));
+ } else if (isHeader(name)) {
+ validateNestedMarkup(name, htmlElementStack);
+ append(createSeamTextHeader(name));
+ }
+
+ } else {
+ append("<");
+ append(name.getText());
+ }
+ htmlElementStack.push(name);
+
+
+ }
+ catch (RecognitionException ex) {
+
+ if (htmlElementStack.isEmpty()) throw ex;
+ Token tok = htmlElementStack.peek();
+ if (tok != null) {
+ throw new HtmlRecognitionException(tok, ex);
+ } else {
+ throw ex;
+ }
+
+ }
+ }
+
+ public final void attribute() throws RecognitionException, TokenStreamException {
+
+ Token att = null;
+
+ try { // for error handling
+ att = LT(1);
+ match(ALPHANUMERICWORD);
+ {
+ _loop422:
+ do {
+ if ((LA(1)==SPACE)) {
+ space();
+ }
+ else {
+ break _loop422;
+ }
+
+ } while (true);
+ }
+ match(EQ);
+ {
+ _loop424:
+ do {
+ if ((LA(1)==SPACE)) {
+ space();
+ }
+ else {
+ break _loop424;
+ }
+
+ } while (true);
+ }
+ match(DOUBLEQUOTE);
+
+ Token token = htmlElementStack.peek();
+ sanitizer.validateHtmlAttribute(token, att);
+ boolean isSeamTextProcessed = isSeamTextElement(token);
+
+ if (!isSeamTextProcessed) {
+ append(att.getText());
+ append("=\"");
+ }
+ beginCapture();
+
+ attributeValue();
+
+ String attValue = endCapture();
+ sanitizer.validateHtmlAttributeValue(token, att, attValue);
+
+ if (!isSeamTextProcessed) {
+ append(attValue);
+ } else if(isLink(token) && "href".equals(att.getText())) {
+
+ linkHolder = attValue;
+ }
+
+
+ match(DOUBLEQUOTE);
+
+ if(!isSeamTextProcessed) {
+ append("\"");
+ }
+
+ }
+ catch (RecognitionException ex) {
+
+ if (htmlElementStack.isEmpty()) throw ex;
+ Token tok = htmlElementStack.peek();
+ if (tok != null) {
+ throw new HtmlRecognitionException(tok, ex);
+ } else {
+ throw ex;
+ }
+
+ }
+ }
+
+ public final void beforeBody() throws RecognitionException, TokenStreamException {
+
+
+ try { // for error handling
+ match(GT);
+
+ Token name = htmlElementStack.peek();
+ if(isSeamTextElement(name)){
+ append(createSimpleSeamText(name));
+ } else {
+ append(">");
+ }
+
+ }
+ catch (RecognitionException ex) {
+
+ if (htmlElementStack.isEmpty()) throw ex;
+ Token tok = htmlElementStack.peek();
+ if (tok != null) {
+ throw new HtmlRecognitionException(tok, ex);
+ } else {
+ throw ex;
+ }
+
+ }
+ }
+
+ public final void body() throws RecognitionException, TokenStreamException {
+
+ Token newline = null;
+
+ {
+
+ Token token = htmlElementStack.peek();
+ boolean isLink = isLink(token);
+ linkValueCollector = new StringBuilder();
+
+ {
+ _loop415:
+ do {
+ switch ( LA(1)) {
+ case STAR:
+ case BAR:
+ case HAT:
+ case PLUS:
+ case EQ:
+ case HASH:
+ case ESCAPE:
+ case TWIDDLE:
+ case OPEN:
+ case CLOSE:
+ case BACKTICK:
+ case GT:
+ {
+ seamCharacters();
+ break;
+ }
+ case ALPHANUMERICWORD:
+ case UNICODEWORD:
+ case PUNCTUATION:
+ case SINGLEQUOTE:
+ case SLASH:
+ case SPACE:
+ {
+ if(isLink) {
+ beginCapture();
+ }
+
+
+ plain();
+
+ if(isLink) {
+ String plain = endCapture();
+ linkValueCollector.append(plain);
+ }
+
+
+ break;
+ }
+ case DOUBLEQUOTE:
+ case ESCAPED_LT:
+ case ESCAPED_GT:
+ case ESCAPED_AMP:
+ case ESCAPED_QOUT:
+ {
+ htmlSpecialChars();
+
+ if(isLink) {
+ String message = "unexpected token";
+ throw new SemanticException(message);
+ }
+
+ break;
+ }
+ case NEWLINE:
+ {
+ newline = LT(1);
+ match(NEWLINE);
+ break;
+ }
+ default:
+ if ((LA(1)==LT) && (LA(2)==ALPHANUMERICWORD)) {
+ html();
+ }
+ else {
+ break _loop415;
+ }
+ }
+ } while (true);
+ }
+ }
+ }
+
+ public final void closeTagWithBody() throws RecognitionException, TokenStreamException {
+
+ Token name = null;
+
+ match(LT);
+ match(SLASH);
+ name = LT(1);
+ match(ALPHANUMERICWORD);
+ match(GT);
+
+ if(isSeamTextElement(name)){
+ if(isLink(name)){
+ append(createSeamTextLink(linkHolder,linkValueCollector.toString().trim()));
+ } else {
+ append(createSimpleSeamText(name));
+ }
+
+ if(isListItem(name) || isHeader(name)) {
+ append("\n");
+ validateHeaderMarkup(name,htmlElementStack);
+ }
+
+ } else {
+ append("</");
+ append(name.getText());
+ append(">");
+ }
+
+
+ htmlElementStack.pop();
+
+ }
+
+ public final void closeTagWithNoBody() throws RecognitionException, TokenStreamException {
+
+
+ match(SLASH);
+ match(GT);
+ append("/>");
+ htmlElementStack.pop();
+
+ }
+
+ public final void attributeValue() throws RecognitionException, TokenStreamException {
+
+ Token an = null;
+ Token p = null;
+ Token s = null;
+
+ try { // for error handling
+ {
+ _loop427:
+ do {
+ switch ( LA(1)) {
+ case AMPERSAND:
+ {
+ match(AMPERSAND);
+ append("&");
+ break;
+ }
+ case ALPHANUMERICWORD:
+ {
+ an = LT(1);
+ match(ALPHANUMERICWORD);
+ append( an.getText() );
+ break;
+ }
+ case PUNCTUATION:
+ {
+ p = LT(1);
+ match(PUNCTUATION);
+ append( p.getText() );
+ break;
+ }
+ case SLASH:
+ {
+ s = LT(1);
+ match(SLASH);
+ append( s.getText() );
+ break;
+ }
+ case SPACE:
+ {
+ space();
+ break;
+ }
+ case STAR:
+ case BAR:
+ case HAT:
+ case PLUS:
+ case EQ:
+ case HASH:
+ case ESCAPE:
+ case TWIDDLE:
+ case UNDERSCORE:
+ {
+ specialChars();
+ break;
+ }
+ default:
+ {
+ break _loop427;
+ }
+ }
+ } while (true);
+ }
+ }
+ catch (RecognitionException ex) {
+
+ if (htmlElementStack.isEmpty()) throw ex;
+ Token tok = htmlElementStack.peek();
+ if (tok != null) {
+ throw new HtmlRecognitionException(tok, ex);
+ } else {
+ throw ex;
+ }
+
+ }
+ }
+
+
+ public static final String[] _tokenNames = {
+ "<0>",
+ "the end of the text",
+ "<2>",
+ "NULL_TREE_LOOKAHEAD",
+ "letters or digits",
+ "letters or digits",
+ "a doublequote \\\"",
+ "ESCAPED_LT",
+ "ESCAPED_GT",
+ "ESCAPED_AMP",
+ "ESCAPED_QOUT",
+ "a punctuation character",
+ "a single quote '",
+ "a slash '/'",
+ "a star '*'",
+ "a bar or pipe '|'",
+ "a caret '^'",
+ "a plus '+'",
+ "an equals '='",
+ "a hash '#'",
+ "the escaping blackslash '\\'",
+ "a tilde '~'",
+ "an underscore '_'",
+ "an opening square bracket '['",
+ "a closing square bracket ']'",
+ "a backtick '`'",
+ "a closing angle bracket '>'",
+ "a space or tab",
+ "a newline",
+ "an opening angle bracket '<'",
+ "an ampersand '&'"
+ };
+
+ private static final long[] mk_tokenSet_0() {
+ long[] data = { 801112048L, 0L};
+ return data;
+ }
+ public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
+
+ }
Added: trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParserTokenTypes.java
===================================================================
--- trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParserTokenTypes.java (rev 0)
+++ trunk/sandbox/ui/editor/src/main/java/org/richfaces/antlr/HtmlSeamTextParserTokenTypes.java 2008-10-30 10:04:25 UTC (rev 10975)
@@ -0,0 +1,35 @@
+// $ANTLR : "html-seamtext.g" -> "HtmlSeamTextLexer.java"$
+
+ package org.richfaces.antlr;
+
+public interface HtmlSeamTextParserTokenTypes {
+ int EOF = 1;
+ int NULL_TREE_LOOKAHEAD = 3;
+ int ALPHANUMERICWORD = 4;
+ int UNICODEWORD = 5;
+ int DOUBLEQUOTE = 6;
+ int ESCAPED_LT = 7;
+ int ESCAPED_GT = 8;
+ int ESCAPED_AMP = 9;
+ int ESCAPED_QOUT = 10;
+ int PUNCTUATION = 11;
+ int SINGLEQUOTE = 12;
+ int SLASH = 13;
+ int STAR = 14;
+ int BAR = 15;
+ int HAT = 16;
+ int PLUS = 17;
+ int EQ = 18;
+ int HASH = 19;
+ int ESCAPE = 20;
+ int TWIDDLE = 21;
+ int UNDERSCORE = 22;
+ int OPEN = 23;
+ int CLOSE = 24;
+ int BACKTICK = 25;
+ int GT = 26;
+ int SPACE = 27;
+ int NEWLINE = 28;
+ int LT = 29;
+ int AMPERSAND = 30;
+}
16 years, 2 months
JBoss Rich Faces SVN: r10974 - in trunk/test-applications/seleniumTest/richfaces/src: main/webapp/pages/ajaxPush and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: dsvyatobatsko
Date: 2008-10-30 04:51:11 -0400 (Thu, 30 Oct 2008)
New Revision: 10974
Added:
trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxPush/ajaxPushAutoTest.xhtml
Modified:
trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/AjaxPushTestBean.java
trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxPushTest.java
Log:
https://jira.jboss.org/jira/browse/RF-4746
https://jira.jboss.org/jira/browse/RF-4747
Modified: trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/AjaxPushTestBean.java
===================================================================
--- trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/AjaxPushTestBean.java 2008-10-30 00:26:08 UTC (rev 10973)
+++ trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/AjaxPushTestBean.java 2008-10-30 08:51:11 UTC (rev 10974)
@@ -18,7 +18,25 @@
private int eventsSent = 0;
+ private String content = "content";
+
/**
+ * Gets value of content field.
+ * @return value of content field
+ */
+ public String getContent() {
+ return content;
+ }
+
+ /**
+ * Set a new value for content field.
+ * @param content a new value for content field
+ */
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ /**
* Gets value of eventsSent field.
* @return value of eventsSent field
*/
@@ -85,4 +103,8 @@
this.enabled = enabled;
}
+ public void restart() {
+ stop();
+ start();
+ }
}
Added: trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxPush/ajaxPushAutoTest.xhtml
===================================================================
(Binary files differ)
Property changes on: trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxPush/ajaxPushAutoTest.xhtml
___________________________________________________________________
Name: svn:mime-type
+ application/xhtml+xml
Modified: trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxPushTest.java
===================================================================
--- trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxPushTest.java 2008-10-30 00:26:08 UTC (rev 10973)
+++ trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxPushTest.java 2008-10-30 08:51:11 UTC (rev 10974)
@@ -1,23 +1,39 @@
package org.richfaces.testng;
+import java.util.HashMap;
+import java.util.Map;
+
import org.ajax4jsf.template.Template;
+import org.richfaces.AutoTester;
import org.richfaces.SeleniumTestBase;
import org.testng.Assert;
import org.testng.annotations.Test;
public class AjaxPushTest extends SeleniumTestBase {
+ private final static String RESTART_RESET = "#{ajaxPushBean.restart}";
+
+ private final static String STOP_RESET = "#{ajaxPushBean.stop}";
+
+ private static Map<String, String> params = new HashMap<String, String>();
+
+ static {
+ params.put("parameter1", "value1");
+ params.put("parameter2", "value2");
+ params.put("parameter3", "value3");
+ }
+
@Test
public void testAjaxPushComponent(Template template) throws Exception {
- renderPage(template);
-
+ renderPage(template, STOP_RESET);
+
String parentId = getParentId() + "_form:";
String startBtnID = parentId + "startButton";
- String stopBtnID = parentId + "stopButton";
+ String stopBtnID = parentId + "stopButton";
- String startPanelID = parentId + "startPanel";
- String progressPanelID = parentId + "progressPanel";
+ String startPanelID = parentId + "startPanel";
+ String progressPanelID = parentId + "progressPanel";
writeStatus("Check layout before start pushing");
@@ -47,7 +63,7 @@
int eventAfter = getEventsCount();
- if(eventBefore >= eventAfter) {
+ if (eventBefore >= eventAfter) {
Assert.fail("PushEvents are not fired");
}
@@ -65,6 +81,33 @@
}
+ @Test
+ public void testNestedParams(Template template) {
+ AutoTester tester = getAutoTester(this);
+ tester.renderPage(template, RESTART_RESET);
+ writeStatus("Test component encodes nested f:param tags and their values are present as request parameters");
+ tester.testRequestParameters(params);
+ }
+
+ @Test
+ public void testRenderedAttribute(Template template) {
+ AutoTester tester = getAutoTester(this);
+ tester.renderPage(template, null);
+ writeStatus("Test component with rendered = false is not present on the page");
+ tester.testRendered();
+ }
+
+ @Override
+ public void sendAjax() {
+ delay(1500);
+ }
+
+ @Override
+ public void setInternalValidationFailed() {
+ String childCompId = getAutoTester(this).getClientId("") + "child";
+ setValueById(childCompId, "");
+ }
+
private int getEventsCount() throws Exception {
String events = getTextById(getParentId() + "_form:events");
try {
@@ -80,4 +123,9 @@
return "pages/ajaxPush/ajaxPushTest.xhtml";
}
+ @Override
+ public String getAutoTestUrl() {
+ return "pages/ajaxPush/ajaxPushAutoTest.xhtml";
+ }
+
}
16 years, 2 months
JBoss Rich Faces SVN: r10973 - in branches/jsf2.0: framework and 25 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: alexsmirnov
Date: 2008-10-29 20:26:08 -0400 (Wed, 29 Oct 2008)
New Revision: 10973
Added:
branches/jsf2.0/examples/createProject.bat
branches/jsf2.0/examples/createProject.sh
branches/jsf2.0/framework/jsf-test/
branches/jsf2.0/framework/jsf-test/pom.xml
branches/jsf2.0/framework/jsf-test/src/
branches/jsf2.0/framework/jsf-test/src/main/
branches/jsf2.0/framework/jsf-test/src/main/java/
branches/jsf2.0/framework/jsf-test/src/main/java/org/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizablePhantomReference.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReference.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReferenceQueue.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableSoftReference.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableWeakReference.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Function.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Functions.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Join.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Nullable.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Objects.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Preconditions.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicate.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicates.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/ReferenceType.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Supplier.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Suppliers.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/package-info.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterable.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterator.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapBasedMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapEntry.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultisetEntry.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractRemovableIterator.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ArrayListMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/BiMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ClassToInstanceMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Collections2.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Comparators.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ConcurrentMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraint.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraints.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumBiMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumHashBiMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingCollection.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingConcurrentMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingIterator.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingList.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingListIterator.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMapEntry.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingObject.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingQueue.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSet.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedSet.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashBiMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Hashing.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableBiMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableCollection.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableList.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSet.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSortedSet.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterables.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterators.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ListMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Lists.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraint.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraints.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Maps.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimaps.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multisets.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/NpeThrowingAbstractMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ObjectArrays.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Ordering.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PeekingIterator.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PrimitiveArrays.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ReferenceMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Serialization.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SetMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Sets.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SortedSetMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardBiMap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardListMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSetMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSortedSetMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Synchronized.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultimap.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultiset.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/UnmodifiableIterator.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/package-info.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/HttpMethod.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/LocalServer.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerConnection.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerLogger.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/TestException.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ClasspathServerResource.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResource.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcePath.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcesDirectory.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServletContainer.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StaticServlet.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpRequest.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpResponse.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpSession.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletConfig.java
branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletContext.java
branches/jsf2.0/framework/jsf-test/src/main/resources/
branches/jsf2.0/framework/jsf-test/src/main/resources/org/
branches/jsf2.0/framework/jsf-test/src/main/resources/org/richfaces/
branches/jsf2.0/framework/jsf-test/src/main/resources/org/richfaces/test/
branches/jsf2.0/framework/jsf-test/src/main/resources/org/richfaces/test/LogMessages.properties
branches/jsf2.0/framework/jsf-test/src/test/
branches/jsf2.0/framework/jsf-test/src/test/java/
branches/jsf2.0/framework/jsf-test/src/test/java/org/
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/FacesServerTest.java
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourcePathTest.java
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourceTest.java
branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServletTest.java
branches/jsf2.0/framework/jsf-test/src/test/resources/
branches/jsf2.0/framework/jsf-test/src/test/resources/org/
branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/
branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/
branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/resource.txt
branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/web.xml
Modified:
branches/jsf2.0/examples/pom.xml
branches/jsf2.0/framework/pom.xml
Log:
test server execute JSF request
Copied: branches/jsf2.0/examples/createProject.bat (from rev 10643, trunk/samples/createProject.bat)
===================================================================
--- branches/jsf2.0/examples/createProject.bat (rev 0)
+++ branches/jsf2.0/examples/createProject.bat 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1 @@
+mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsfwebapp -DarchetypeVersion=4.0.0-SNAPSHOT -DgroupId=org.richfaces -DartifactId=%1
\ No newline at end of file
Copied: branches/jsf2.0/examples/createProject.sh (from rev 10643, trunk/samples/createProject.sh)
===================================================================
--- branches/jsf2.0/examples/createProject.sh (rev 0)
+++ branches/jsf2.0/examples/createProject.sh 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,3 @@
+#!/bin/sh
+mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsfwebapp \
+ -DarchetypeVersion=4.0.0-SNAPSHOT -Dversion=4.0.0-SNAPSHOT -DgroupId=org.richfaces.examples -DartifactId=$1
Modified: branches/jsf2.0/examples/pom.xml
===================================================================
--- branches/jsf2.0/examples/pom.xml 2008-10-29 20:26:23 UTC (rev 10972)
+++ branches/jsf2.0/examples/pom.xml 2008-10-30 00:26:08 UTC (rev 10973)
@@ -46,4 +46,7 @@
<version>${project.version}</version>
</dependency>
</dependencies>
+ <modules>
+ <module>repeater</module>
+ </modules>
</project>
\ No newline at end of file
Added: branches/jsf2.0/framework/jsf-test/pom.xml
===================================================================
--- branches/jsf2.0/framework/jsf-test/pom.xml (rev 0)
+++ branches/jsf2.0/framework/jsf-test/pom.xml 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<project>
+ <parent>
+ <artifactId>framework</artifactId>
+ <groupId>org.richfaces</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>jsf-test</artifactId>
+ <name>jsf-test</name>
+ <version>4.0.0-SNAPSHOT</version>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.htmlunit</groupId>
+ <artifactId>htmlunit</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>mojarra-jsf-impl</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>el-impl</groupId>
+ <artifactId>el-impl</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizablePhantomReference.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizablePhantomReference.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizablePhantomReference.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.lang.ref.PhantomReference;
+
+/**
+ * Phantom reference with a {@code finalizeReferent()} method which a
+ * background thread invokes after the garbage collector reclaims the
+ * referent. This is a simpler alternative to using a {@link
+ * java.lang.ref.ReferenceQueue}.
+ *
+ * @author Bob Lee
+ */
+public abstract class FinalizablePhantomReference<T>
+ extends PhantomReference<T> implements FinalizableReference {
+
+ protected FinalizablePhantomReference(T referent) {
+ super(referent, FinalizableReferenceQueue.getInstance());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReference.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReference.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReference.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+/**
+ * Package-private interface implemented by references that have code to run
+ * after garbage collection of their referents.
+ *
+ * @author Bob Lee
+ */
+interface FinalizableReference {
+
+ /**
+ * Invoked on a background thread after the referent has been garbage
+ * collected.
+ */
+ void finalizeReferent();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReferenceQueue.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReferenceQueue.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableReferenceQueue.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Starts a background thread that cleans up after reclaimed referents.
+ *
+ * @author Bob Lee
+ */
+class FinalizableReferenceQueue extends ReferenceQueue<Object> {
+
+ private static final Logger logger =
+ Logger.getLogger(FinalizableReferenceQueue.class.getName());
+
+ /**
+ * Returns the singleton instance.
+ */
+ public static ReferenceQueue<Object> getInstance() {
+ return LazyInstanceHolder.queue;
+ }
+
+ private static class LazyInstanceHolder {
+ static final ReferenceQueue<Object> queue = new FinalizableReferenceQueue();
+ }
+
+ private FinalizableReferenceQueue() {
+ start();
+ }
+
+ void start() {
+ Thread thread = new Thread(getClass().getSimpleName()) {
+ @Override public void run() {
+ while (true) {
+ try {
+ cleanUp(remove());
+ } catch (InterruptedException e) { /* ignore */ }
+ }
+ }
+ };
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ void cleanUp(Reference<?> reference) {
+ try {
+ ((FinalizableReference) reference).finalizeReferent();
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
+ }
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableSoftReference.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableSoftReference.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableSoftReference.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.lang.ref.SoftReference;
+
+/**
+ * Soft reference with a {@code finalizeReferent()} method which a background
+ * thread invokes after the garbage collector reclaims the referent. This is a
+ * simpler alternative to using a {@link java.lang.ref.ReferenceQueue}.
+ *
+ * @author Bob Lee
+ */
+public abstract class FinalizableSoftReference<T> extends SoftReference<T>
+ implements FinalizableReference {
+
+ protected FinalizableSoftReference(T referent) {
+ super(referent, FinalizableReferenceQueue.getInstance());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableWeakReference.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableWeakReference.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/FinalizableWeakReference.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Weak reference with a {@code finalizeReferent()} method which a background
+ * thread invokes after the garbage collector reclaims the referent. This is a
+ * simpler alternative to using a {@link java.lang.ref.ReferenceQueue}.
+ *
+ * @author Bob Lee
+ */
+public abstract class FinalizableWeakReference<T> extends WeakReference<T>
+ implements FinalizableReference {
+
+ protected FinalizableWeakReference(T referent) {
+ super(referent, FinalizableReferenceQueue.getInstance());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Function.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Function.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Function.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+/**
+ * A transformation from one object to another. For example, a
+ * {@code StringToIntegerFunction} may implement
+ * <code>Function<String,Integer></code> and transform integers in
+ * {@code String} format to {@code Integer} format.
+ *
+ * <p>The transformation on the source object does not necessarily result in
+ * an object of a different type. For example, a
+ * {@code FarenheitToCelsiusFunction} may implement
+ * <code>Function<Float,Float></code>.
+ *
+ * <p>Implementations which may cause side effects upon evaluation are strongly
+ * encouraged to state this fact clearly in their API documentation.
+ *
+ * @param <F> the type of the function input
+ * @param <T> the type of the function output
+ * @author Kevin Bourrillion
+ * @author Scott Bonneau
+ */
+public interface Function<F, T> {
+
+ /**
+ * Applies the function to an object of type {@code F}, resulting in an object
+ * of type {@code T}. Note that types {@code F} and {@code T} may or may not
+ * be the same.
+ *
+ * @param from the source object
+ * @return the resulting object
+ */
+ T apply(@Nullable F from);
+
+ /**
+ * Indicates whether some other object is equal to this {@code Function}.
+ * This method can return {@code true} <i>only</i> if the specified object is
+ * also a {@code Function} and, for every input object {@code o}, it returns
+ * exactly the same value. Thus, {@code function1.equals(function2)} implies
+ * that either {@code function1.apply(o)} and {@code function2.apply(o)} are
+ * both null, or {@code function1.apply(o).equals(function2.apply(o))}.
+ *
+ * <p>Note that it is always safe <em>not</em> to override
+ * {@link Object#equals}.
+ */
+ boolean equals(@Nullable Object obj);
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Functions.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Functions.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Functions.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Useful functions.
+ *
+ * @author Mike Bostock
+ * @author Vlad Patryshev
+ * @author Jared Levy
+ */
+public final class Functions {
+ private Functions() { }
+
+ /**
+ * A function that calls {@code toString()} on its argument. This function
+ * does not accept nulls; it will throw a {@link NullPointerException} when
+ * applied to {@code null}.
+ *
+ * <p>TODO: Consider deprecating this in favor of {@link #toStringFunction()}.
+ */
+ public static final Function<Object, String> TO_STRING =
+ ToStringFunction.INSTANCE;
+
+ /**
+ * Returns a function that calls {@code toString()} on its argument. The
+ * function does not accept nulls; it will throw a
+ * {@link NullPointerException} when applied to {@code null}.
+ */
+ @SuppressWarnings("unchecked") // see comment below
+ public static <F> Function<F, String> toStringFunction() {
+ /*
+ * Function<F, T> is contravariant on F, so this is essentially a widening
+ * cast. Note: IntelliJ incorrectly colors the following line red.
+ */
+ return (Function<F, String>) ToStringFunction.INSTANCE;
+ }
+
+ // enum singleton pattern
+ private enum ToStringFunction implements Function<Object, String> {
+ INSTANCE;
+
+ public String apply(Object o) {
+ return o.toString();
+ }
+
+ @Override public String toString() {
+ return "toString";
+ }
+ }
+
+ /**
+ * Returns a function that determines the hash code of its argument. For null
+ * arguments, the function returns 0, for consistency with the hash code
+ * calculations in the Java Collections classes.
+ */
+ public static Function<Object, Integer> toHashCode() {
+ return HashCodeFunction.INSTANCE;
+ }
+
+ // enum singleton pattern
+ private enum HashCodeFunction implements Function<Object, Integer> {
+ INSTANCE;
+
+ public Integer apply(Object o) {
+ return (o == null) ? 0 : o.hashCode();
+ }
+
+ @Override public String toString() {
+ return "hashCode";
+ }
+ }
+
+ // enum singleton pattern
+ private enum TrimStringFunction implements Function<String, String> {
+ INSTANCE;
+
+ public String apply(String string) {
+ return string.trim();
+ }
+
+ @Override public String toString() {
+ return "String.trim";
+ }
+ }
+
+ /**
+ * Returns the identity function.
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> Function<E, E> identity() {
+ return (Function<E, E>) IdentityFunction.INSTANCE;
+ }
+
+ // enum singleton pattern
+ private enum IdentityFunction implements Function<Object, Object> {
+ INSTANCE;
+
+ public Object apply(Object o) {
+ return o;
+ }
+
+ @Override public String toString() {
+ return "identity";
+ }
+ }
+
+ /**
+ * Returns a function which performs a map lookup.
+ *
+ * <p>The difference between a map and a function is that a map is defined on
+ * a set of keys, while a function is defined on all inputs of the correct
+ * type. The function created by this method returns {@code null} for all
+ * inputs that do not belong to the map's key set.
+ *
+ * @param map source map that determines the function behavior
+ * @return function that returns {@code map.get(a)} for each {@code a}
+ */
+ public static <A, B> Function<A, B> forMap(
+ final Map<? super A, ? extends B> map) {
+ return new FunctionForMapNoDefault<A, B>(map);
+ }
+
+ private static class FunctionForMapNoDefault<A, B>
+ implements Function<A, B>, Serializable {
+ private final Map<? super A, ? extends B> map;
+
+ public FunctionForMapNoDefault(
+ Map<? super A, ? extends B> map) {
+ this.map = checkNotNull(map);
+ }
+ public B apply(A a) {
+ return map.get(a);
+ }
+ @Override public boolean equals(Object o) {
+ if (o instanceof FunctionForMapNoDefault) {
+ FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
+ return map.equals(that.map);
+ }
+ return false;
+ }
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+ @Override public String toString() {
+ return "forMap(" + map + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a function which performs a map lookup with a default value. The
+ * function created by this method returns {@code defaultValue} for all
+ * inputs that do not belong to the map's key set.
+ *
+ * @param map source map that determines the function behavior
+ * @param defaultValue the value to return for inputs that aren't map keys
+ * @return function that returns {@code map.get(a)} when {@code a} is a key,
+ * or {@code defaultValue} otherwise
+ */
+ public static <A, B> Function<A, B> forMap(
+ Map<? super A, ? extends B> map, @Nullable final B defaultValue) {
+ if (defaultValue == null) {
+ return forMap(map);
+ }
+ return new ForMapWithDefault<A, B>(map, defaultValue);
+ }
+
+ private static class ForMapWithDefault<A, B>
+ implements Function<A, B>, Serializable {
+ private final Map<? super A, ? extends B> map;
+ private final B defaultValue;
+
+ public ForMapWithDefault(Map<? super A, ? extends B> map, B defaultValue) {
+ this.map = checkNotNull(map);
+ this.defaultValue = defaultValue;
+ }
+ public B apply(A a) {
+ return map.containsKey(a) ? map.get(a) : defaultValue;
+ }
+ @Override public boolean equals(Object o) {
+ if (o instanceof ForMapWithDefault) {
+ ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
+ return map.equals(that.map) && defaultValue.equals(that.defaultValue);
+ }
+ return false;
+ }
+ @Override public int hashCode() {
+ return map.hashCode() + defaultValue.hashCode();
+ }
+ @Override public String toString() {
+ return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns the composition of two functions. For {@code f: A->B} and
+ * {@code g: B->C}, composition is defined as the function h such that
+ * {@code h(a) == g(f(a))} for each {@code a}.
+ *
+ * @see <a href="//en.wikipedia.org/wiki/Function_composition">
+ * function composition</a>
+ *
+ * @param g the second function to apply
+ * @param f the first function to apply
+ * @return the composition of {@code f} and {@code g}
+ */
+ public static <A, B, C> Function<A, C> compose(
+ final Function<? super B, ? extends C> g,
+ final Function<? super A, ? extends B> f) {
+ return new FunctionComposition<A, B, C>(g, f);
+ }
+
+ private static class FunctionComposition<A, B, C>
+ implements Function<A, C>, Serializable {
+ private final Function<? super B, ? extends C> g;
+ private final Function<? super A, ? extends B> f;
+
+ public FunctionComposition(Function<? super B, ? extends C> g,
+ Function<? super A, ? extends B> f) {
+ this.g = checkNotNull(g);
+ this.f = checkNotNull(f);
+ }
+ public C apply(A a) {
+ return g.apply(f.apply(a));
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof FunctionComposition) {
+ FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
+ return f.equals(that.f) && g.equals(that.g);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ /*
+ * TODO: To leave the door open for future enhancement, this
+ * calculation should be coordinated with the hashCode() method of the
+ * corresponding composition method in Predicates. To construct the
+ * composition:
+ * predicate(function2(function1(x)))
+ *
+ * There are two different ways of composing it:
+ * compose(predicate, compose(function2, function1))
+ * compose(compose(predicate, function2), function1)
+ *
+ * It would be nice if these could be equal.
+ */
+ return f.hashCode() ^ g.hashCode();
+ }
+ @Override public String toString() {
+ return g.toString() + "(" + f.toString() + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a function that returns the same boolean output as the given
+ * predicate for all inputs.
+ */
+ public static <T> Function<T, Boolean> forPredicate(
+ Predicate<? super T> predicate) {
+ return new PredicateFunction<T>(predicate);
+ }
+
+ /** @see Functions#forPredicate */
+ private static class PredicateFunction<T>
+ implements Function<T, Boolean>, Serializable {
+ private final Predicate<? super T> predicate;
+
+ private PredicateFunction(Predicate<? super T> predicate) {
+ this.predicate = checkNotNull(predicate);
+ }
+
+ public Boolean apply(T t) {
+ return predicate.apply(t);
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof PredicateFunction) {
+ PredicateFunction<?> that = (PredicateFunction<?>) obj;
+ return predicate.equals(that.predicate);
+ }
+ return false;
+ }
+ @Override public int hashCode() {
+ return predicate.hashCode();
+ }
+ @Override public String toString() {
+ return "forPredicate(" + predicate + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a function that returns {@code value} for any input.
+ *
+ * @param value the constant value for the function to return
+ * @return a function that always returns {@code value}
+ */
+ public static <E> Function<Object, E> constant(@Nullable E value) {
+ return new ConstantFunction<E>(value);
+ }
+
+ private static class ConstantFunction<E>
+ implements Function<Object, E>, Serializable {
+ private final E value;
+
+ public ConstantFunction(@Nullable E value) {
+ this.value = value;
+ }
+ public E apply(Object from) {
+ return value;
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof ConstantFunction) {
+ ConstantFunction<?> that = (ConstantFunction<?>) obj;
+ return Objects.equal(value, that.value);
+ }
+ return false;
+ }
+ @Override public int hashCode() {
+ return (value == null) ? 0 : value.hashCode();
+ }
+ @Override public String toString() {
+ return "constant(" + value + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Join.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Join.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Join.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.IOException;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Utility for joining pieces of text separated by a delimiter. It can handle
+ * iterators, collections, arrays, and varargs, and can append to any
+ * {@link Appendable} or just return a {@link String}. For example,
+ * {@code join(":", "a", "b", "c")} returns {@code "a:b:c"}.
+ *
+ * <p>All methods of this class throw {@link NullPointerException} when a value
+ * of {@code null} is supplied for any parameter. The elements within the
+ * collection, iterator, array, or varargs parameter list <i>may</i> be null --
+ * these will be represented in the output by the string {@code "null"}.
+ *
+ * @author Kevin Bourrillion
+ */
+public final class Join {
+ private Join() {}
+
+ /**
+ * Returns a string containing the {@code tokens}, converted to strings if
+ * necessary, separated by {@code delimiter}. If {@code tokens} is empty, it
+ * returns an empty string.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param tokens objects to append
+ * @return a string consisting of the joined elements
+ */
+ public static String join(String delimiter, Iterable<?> tokens) {
+ return join(delimiter, tokens.iterator());
+ }
+
+ /**
+ * Returns a string containing the {@code tokens}, converted to strings if
+ * necessary, separated by {@code delimiter}. If {@code tokens} is empty, it
+ * returns an empty string.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param tokens objects to append
+ * @return a string consisting of the joined elements
+ */
+ public static String join(String delimiter, Object[] tokens) {
+ return join(delimiter, Arrays.asList(tokens));
+ }
+
+ /**
+ * Returns a string containing the {@code tokens}, converted to strings if
+ * necessary, separated by {@code delimiter}.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param firstToken the first object to append
+ * @param otherTokens subsequent objects to append
+ * @return a string consisting of the joined elements
+ */
+ public static String join(
+ String delimiter, @Nullable Object firstToken, Object... otherTokens) {
+ checkNotNull(otherTokens);
+ return join(delimiter, asList(firstToken, otherTokens));
+ }
+
+ /**
+ * Returns a string containing the {@code tokens}, converted to strings if
+ * necessary, separated by {@code delimiter}. If {@code tokens} is empty, it
+ * returns an empty string.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param tokens objects to append
+ * @return a string consisting of the joined elements
+ */
+ public static String join(String delimiter, Iterator<?> tokens) {
+ StringBuilder sb = new StringBuilder();
+ join(sb, delimiter, tokens);
+ return sb.toString();
+ }
+
+ /**
+ * Returns a string containing the contents of {@code map}, with entries
+ * separated by {@code entryDelimiter}, and keys and values separated with
+ * {@code keyValueSeparator}.
+ *
+ * <p>Each key and value will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param keyValueSeparator a string to append between every key and its
+ * associated value
+ * @param entryDelimiter a string to append between every entry, but not at
+ * the beginning or end
+ * @param map the map containing the data to join
+ * @return a string consisting of the joined entries of the map; empty if the
+ * map is empty
+ */
+ public static String join(
+ String keyValueSeparator, String entryDelimiter, Map<?, ?> map) {
+ return join(new StringBuilder(), keyValueSeparator, entryDelimiter, map)
+ .toString();
+ }
+
+ /**
+ * Appends each of the {@code tokens} to {@code appendable}, separated by
+ * {@code delimiter}.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param appendable the object to append the results to
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param tokens objects to append
+ * @return the same {@code Appendable} instance that was passed in
+ * @throws JoinException if an {@link IOException} occurs
+ */
+ public static <T extends Appendable> T join(
+ T appendable, String delimiter, Iterable<?> tokens) {
+ return join(appendable, delimiter, tokens.iterator());
+ }
+
+ /**
+ * Appends each of the {@code tokens} to {@code appendable}, separated by
+ * {@code delimiter}.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param appendable the object to append the results to
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param tokens objects to append
+ * @return the same {@code Appendable} instance that was passed in
+ * @throws JoinException if an {@link IOException} occurs
+ */
+ public static <T extends Appendable> T join(
+ T appendable, String delimiter, Object[] tokens) {
+ return join(appendable, delimiter, Arrays.asList(tokens));
+ }
+
+ /**
+ * Appends each of the {@code tokens} to {@code appendable}, separated by
+ * {@code delimiter}.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param appendable the object to append the results to
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param firstToken the first object to append
+ * @param otherTokens subsequent objects to append
+ * @return the same {@code Appendable} instance that was passed in
+ * @throws JoinException if an {@link IOException} occurs
+ */
+ public static <T extends Appendable> T join(T appendable, String delimiter,
+ @Nullable Object firstToken, Object... otherTokens) {
+ checkNotNull(otherTokens);
+ return join(appendable, delimiter, asList(firstToken, otherTokens));
+ }
+
+ /**
+ * Appends each of the {@code tokens} to {@code appendable}, separated by
+ * {@code delimiter}.
+ *
+ * <p>Each token will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param appendable the object to append the results to
+ * @param delimiter a string to append between every element, but not at the
+ * beginning or end
+ * @param tokens objects to append
+ * @return the same {@code Appendable} instance that was passed in
+ * @throws JoinException if an {@link IOException} occurs
+ */
+ public static <T extends Appendable> T join(
+ T appendable, String delimiter, Iterator<?> tokens) {
+
+ /* This method is the workhorse of the class */
+
+ checkNotNull(appendable);
+ checkNotNull(delimiter);
+ if (tokens.hasNext()) {
+ try {
+ appendOneToken(appendable, tokens.next());
+ while (tokens.hasNext()) {
+ appendable.append(delimiter);
+ appendOneToken(appendable, tokens.next());
+ }
+ } catch (IOException e) {
+ throw new JoinException(e);
+ }
+ }
+ return appendable;
+ }
+
+ /**
+ * Appends the contents of {@code map} to {@code appendable}, with entries
+ * separated by {@code entryDelimiter}, and keys and values separated with
+ * {@code keyValueSeparator}.
+ *
+ * <p>Each key and value will be converted to a {@link CharSequence} using
+ * {@link String#valueOf(Object)}, if it isn't a {@link CharSequence} already.
+ * Note that this implies that null tokens will be appended as the
+ * four-character string {@code "null"}.
+ *
+ * @param appendable the object to append the results to
+ * @param keyValueSeparator a string to append between every key and its
+ * associated value
+ * @param entryDelimiter a string to append between every entry, but not at
+ * the beginning or end
+ * @param map the map containing the data to join
+ * @return the same {@code Appendable} instance that was passed in
+ */
+ public static <T extends Appendable> T join(T appendable,
+ String keyValueSeparator, String entryDelimiter, Map<?, ?> map) {
+ checkNotNull(appendable);
+ checkNotNull(keyValueSeparator);
+ checkNotNull(entryDelimiter);
+ Iterator<? extends Map.Entry<?, ?>> entries = map.entrySet().iterator();
+ if (entries.hasNext()) {
+ try {
+ appendOneEntry(appendable, keyValueSeparator, entries.next());
+ while (entries.hasNext()) {
+ appendable.append(entryDelimiter);
+ appendOneEntry(appendable, keyValueSeparator, entries.next());
+ }
+ } catch (IOException e) {
+ throw new JoinException(e);
+ }
+ }
+ return appendable;
+ }
+
+ private static void appendOneEntry(
+ Appendable appendable, String keyValueSeparator, Map.Entry<?, ?> entry)
+ throws IOException {
+ appendOneToken(appendable, entry.getKey());
+ appendable.append(keyValueSeparator);
+ appendOneToken(appendable, entry.getValue());
+ }
+
+ private static void appendOneToken(Appendable appendable, Object token)
+ throws IOException {
+ appendable.append(toCharSequence(token));
+ }
+
+ private static CharSequence toCharSequence(Object token) {
+ return (token instanceof CharSequence)
+ ? (CharSequence) token
+ : String.valueOf(token);
+ }
+
+ /**
+ * Exception thrown in response to an {@link IOException} from the supplied
+ * {@link Appendable}. This is used because most callers won't want to
+ * worry about catching an IOException.
+ */
+ public static class JoinException extends RuntimeException {
+ private JoinException(IOException cause) {
+ super(cause);
+ }
+
+ private static final long serialVersionUID = 1L;
+ }
+
+ /**
+ * Duplicate of
+ * {@link com.google.common.collect.Lists#asList(Object, Object[])}, copied
+ * here to remove dependencies.
+ */
+ private static List<Object> asList(final Object first, final Object[] rest) {
+ return new AbstractList<Object>() {
+ @Override public int size() {
+ return rest.length + 1;
+ }
+ @Override public Object get(int index) {
+ return (index == 0) ? first : rest[index - 1];
+ }
+ };
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Nullable.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Nullable.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Nullable.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The presence of this annotation on a method parameter indicates that
+ * {@code null} is an acceptable value for that parameter. It should not be
+ * used for parameters of primitive types.
+ *
+ * @author Kevin Bourrillion
+ */
+@Documented
+(a)Retention(RetentionPolicy.RUNTIME)
+(a)Target(ElementType.PARAMETER)
+public @interface Nullable { }
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Objects.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Objects.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Objects.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.util.Arrays;
+
+/**
+ * Helper functions that can operate on any {@code Object}.
+ *
+ * @author Laurence Gonsalves
+ */
+public final class Objects {
+ private Objects() {}
+
+ /**
+ * Determines whether two possibly-null objects are equal. Returns:
+ *
+ * <ul>
+ * <li>{@code true} if {@code a} and {@code b} are both null.
+ * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
+ * equal according to {@link Object#equals(Object)}.
+ * <li>{@code false} in all other situations.
+ * </ul>
+ *
+ * <p>This assumes that any non-null objects passed to this function conform
+ * to the {@code equals()} contract.
+ */
+ public static boolean equal(@Nullable Object a, @Nullable Object b) {
+ return a == b || (a != null && a.equals(b));
+ }
+
+ /**
+ * Generates a hash code for multiple values. The hash code is generated by
+ * calling {@link Arrays#hashCode(Object[])}.
+ *
+ * <p>This is useful for implementing {@link Object#hashCode()}. For example,
+ * in an object that has three properties, {@code x}, {@code y}, and
+ * {@code z}, one could write:
+ * <pre>
+ * public int hashCode() {
+ * return Objects.hashCode(getX(), getY(), getZ());
+ * }</pre>
+ *
+ * <b>Warning</b>: When a single object is supplied, the returned hash code
+ * does not equal the hash code of that object.
+ */
+ public static int hashCode(Object... objects) {
+ return Arrays.hashCode(objects);
+ }
+
+ /**
+ * Returns the first of two given parameters that is not {@code null}, if
+ * either is, or otherwise throws a {@link NullPointerException}.
+ *
+ * @return {@code first} if {@code first} is not {@code null}, or
+ * {@code second} if {@code first} is {@code null} and {@code second} is
+ * not {@code null}
+ * @throws NullPointerException if both {@code first} and {@code second} were
+ * {@code null}
+ */
+ public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
+ return first != null ? first : Preconditions.checkNotNull(second);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Preconditions.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Preconditions.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Preconditions.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.util.Collection;
+import java.util.NoSuchElementException;
+
+/**
+ * Simple static methods to be called at the start of your own methods to verify
+ * correct arguments and state. This allows constructs such as
+ * <pre>
+ * if (count <= 0) {
+ * throw new IllegalArgumentException("must be positive: " + count);
+ * }</pre>
+ *
+ * to be replaced with the more compact
+ * <pre>
+ * checkArgument(count > 0, "must be positive: %s", count);</pre>
+ *
+ * Note that the sense of the expression is inverted; with {@code Preconditions}
+ * you declare what you expect to be <i>true</i>, just as you do with an
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html">
+ * {@code assert}</a> or a JUnit {@code assertTrue()} call.
+ *
+ * <p>Take care not to confuse precondition checking with other similar types
+ * of checks! Precondition exceptions -- including those provided here, but also
+ * {@link IndexOutOfBoundsException}, {@link NoSuchElementException}, {@link
+ * UnsupportedOperationException} and others -- are used to signal that the
+ * <i>calling method</i> has made an error. This tells the caller that it should
+ * not have invoked the method when it did, with the arguments it did, or
+ * perhaps <i>ever</i>. Postcondition or other invariant failures should not
+ * throw these types of exceptions.
+ *
+ * <p><b>Note:</b> The methods of the {@code Preconditions} class are highly
+ * unusual in one way: they are <i>supposed to</i> throw exceptions, and promise
+ * in their specifications to do so even when given perfectly valid input. That
+ * is, {@code null} is a valid parameter to the method {@link
+ * #checkNotNull(Object)} -- and technically this parameter could be even marked
+ * as {@link Nullable} -- yet the method will still throw an exception anyway,
+ * because that's what its contract says to do.
+ *
+ * @author Kevin Bourrillion
+ */
+public final class Preconditions {
+ private Preconditions() {}
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the
+ * calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(boolean expression) {
+ if (!expression) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the
+ * calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(boolean expression, Object errorMessage) {
+ if (!expression) {
+ throw new IllegalArgumentException(String.valueOf(errorMessage));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the
+ * calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @throws IllegalArgumentException if {@code expression} is false
+ * @throws NullPointerException if the check fails and either {@code
+ * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
+ * this happen)
+ */
+ public static void checkArgument(boolean expression,
+ String errorMessageTemplate, Object... errorMessageArgs) {
+ if (!expression) {
+ throw new IllegalArgumentException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalStateException if {@code expression} is false
+ */
+ public static void checkState(boolean expression) {
+ if (!expression) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @throws IllegalStateException if {@code expression} is false
+ */
+ public static void checkState(boolean expression, Object errorMessage) {
+ if (!expression) {
+ throw new IllegalStateException(String.valueOf(errorMessage));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling
+ * instance, but not involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @throws IllegalStateException if {@code expression} is false
+ * @throws NullPointerException if the check fails and either {@code
+ * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
+ * this happen)
+ */
+ public static void checkState(boolean expression,
+ String errorMessageTemplate, Object... errorMessageArgs) {
+ if (!expression) {
+ throw new IllegalStateException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ public static <T> T checkNotNull(T reference) {
+ if (reference == null) {
+ throw new NullPointerException();
+ }
+ return reference;
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ public static <T> T checkNotNull(T reference, Object errorMessage) {
+ if (reference == null) {
+ throw new NullPointerException(String.valueOf(errorMessage));
+ }
+ return reference;
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling
+ * method is not null.
+ *
+ * @param reference an object reference
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ public static <T> T checkNotNull(T reference, String errorMessageTemplate,
+ Object... errorMessageArgs) {
+ if (reference == null) {
+ // If either of these parameters is null, the right thing happens anyway
+ throw new NullPointerException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ return reference;
+ }
+
+ /**
+ * Ensures that an {@code Iterable} object passed as a parameter to the
+ * calling method is not null and contains no null elements.
+ *
+ * @param iterable the iterable to check the contents of
+ * @return the non-null {@code iterable} reference just validated
+ * @throws NullPointerException if {@code iterable} is null or contains at
+ * least one null element
+ */
+ public static <T extends Iterable<?>> T checkContentsNotNull(T iterable) {
+ if (containsOrIsNull(iterable)) {
+ throw new NullPointerException();
+ }
+ return iterable;
+ }
+
+ /**
+ * Ensures that an {@code Iterable} object passed as a parameter to the
+ * calling method is not null and contains no null elements.
+ *
+ * @param iterable the iterable to check the contents of
+ * @param errorMessage the exception message to use if the check fails; will
+ * be converted to a string using {@link String#valueOf(Object)}
+ * @return the non-null {@code iterable} reference just validated
+ * @throws NullPointerException if {@code iterable} is null or contains at
+ * least one null element
+ */
+ public static <T extends Iterable<?>> T checkContentsNotNull(
+ T iterable, Object errorMessage) {
+ if (containsOrIsNull(iterable)) {
+ throw new NullPointerException(String.valueOf(errorMessage));
+ }
+ return iterable;
+ }
+
+ /**
+ * Ensures that an {@code Iterable} object passed as a parameter to the
+ * calling method is not null and contains no null elements.
+ *
+ * @param iterable the iterable to check the contents of
+ * @param errorMessageTemplate a template for the exception message should the
+ * check fail. The message is formed by replacing each {@code %s}
+ * placeholder in the template with an argument. These are matched by
+ * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
+ * Unmatched arguments will be appended to the formatted message in square
+ * braces. Unmatched placeholders will be left as-is.
+ * @param errorMessageArgs the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}.
+ * @return the non-null {@code iterable} reference just validated
+ * @throws NullPointerException if {@code iterable} is null or contains at
+ * least one null element
+ */
+ public static <T extends Iterable<?>> T checkContentsNotNull(T iterable,
+ String errorMessageTemplate, Object... errorMessageArgs) {
+ if (containsOrIsNull(iterable)) {
+ throw new NullPointerException(
+ format(errorMessageTemplate, errorMessageArgs));
+ }
+ return iterable;
+ }
+
+ private static boolean containsOrIsNull(Iterable<?> iterable) {
+ if (iterable == null) {
+ return true;
+ }
+
+ if (iterable instanceof Collection) {
+ Collection<?> collection = (Collection<?>) iterable;
+ try {
+ return collection.contains(null);
+ } catch (NullPointerException e) {
+ // A NPE implies that the collection doesn't contain null.
+ return false;
+ }
+ } else {
+ for (Object element : iterable) {
+ if (element == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Substitutes each {@code %s} in {@code template} with an argument. These
+ * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
+ * If there are more arguments than placeholders, the unmatched arguments will
+ * be appended to the end of the formatted message in square braces.
+ *
+ * @param template a non-null string containing 0 or more {@code %s}
+ * placeholders.
+ * @param args the arguments to be substituted into the message
+ * template. Arguments are converted to strings using
+ * {@link String#valueOf(Object)}. Arguments can be null.
+ */
+ // VisibleForTesting
+ static String format(String template, Object... args) {
+ // start substituting the arguments into the '%s' placeholders
+ StringBuilder builder = new StringBuilder(
+ template.length() + 16 * args.length);
+ int templateStart = 0;
+ int i = 0;
+ while (i < args.length) {
+ int placeholderStart = template.indexOf("%s", templateStart);
+ if (placeholderStart == -1) {
+ break;
+ }
+ builder.append(template.substring(templateStart, placeholderStart));
+ builder.append(args[i++]);
+ templateStart = placeholderStart + 2;
+ }
+ builder.append(template.substring(templateStart));
+
+ // if we run out of placeholders, append the extra args in square braces
+ if (i < args.length) {
+ builder.append(" [");
+ builder.append(args[i++]);
+ while (i < args.length) {
+ builder.append(", ");
+ builder.append(args[i++]);
+ }
+ builder.append("]");
+ }
+
+ return builder.toString();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicate.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicate.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicate.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+/**
+ * Determines a true or false value for a given input. For example, a
+ * {@code RegexPredicate} might implement {@code Predicate<String>}, and return
+ * {@code true} for any string that matches its given regular expression.
+ *
+ * <p>Implementations which may cause side effects upon evaluation are strongly
+ * encouraged to state this fact clearly in their API documentation.
+ *
+ * @author Kevin Bourrillion
+ */
+public interface Predicate<T> {
+
+ /*
+ * This interface does not extend Function<T, Boolean> because doing so would
+ * let predicates return null.
+ */
+
+ /**
+ * Applies this predicate to the given object.
+ *
+ * @param input the input that the predicate should act on
+ * @return the value of this predicate when applied to the input {@code t}
+ */
+ boolean apply(@Nullable T input);
+
+
+ /**
+ * Indicates whether some other object is equal to this {@code Predicate}.
+ * This method can return {@code true} <i>only</i> if the specified object is
+ * also a {@code Predicate} and, for every input object {@code input}, it
+ * returns exactly the same value. Thus, {@code predicate1.equals(predicate2)}
+ * implies that either {@code predicate1.apply(input)} and
+ * {@code predicate2.apply(input)} are both {@code true} or both
+ * {@code false}.
+ *
+ * <p>Note that it is always safe <i>not</i> to override
+ * {@link Object#equals}.
+ */
+ boolean equals(@Nullable Object obj);
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicates.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicates.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Predicates.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.richfaces.collections.base;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import static org.richfaces.collections.base.Preconditions.checkContentsNotNull;
+
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * Contains static factory methods for creating {@code Predicate} instances.
+ *
+ * @author Kevin Bourrillion
+ */
+public final class Predicates {
+ private Predicates() {}
+
+ // TODO: considering having these implement a VisitablePredicate interface
+ // which specifies an accept(PredicateVisitor) method.
+
+ /**
+ * Returns a predicate that always evaluates to {@code true}.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Predicate<T> alwaysTrue() {
+ return (Predicate<T>) AlwaysTruePredicate.INSTANCE;
+ }
+
+ /**
+ * Returns a predicate that always evaluates to {@code false}.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Predicate<T> alwaysFalse() {
+ return (Predicate<T>) AlwaysFalsePredicate.INSTANCE;
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object reference
+ * being tested is null.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Predicate<T> isNull() {
+ return (Predicate<T>) IsNullPredicate.INSTANCE;
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object reference
+ * being tested is not null.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Predicate<T> notNull() {
+ return (Predicate<T>) NotNullPredicate.INSTANCE;
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the given predicate
+ * evaluates to {@code false}.
+ */
+ public static <T> Predicate<T> not(Predicate<? super T> predicate) {
+ return new NotPredicate<T>(predicate);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if each of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a false
+ * predicate is found. It does not defensively copy the iterable passed in, so
+ * future changes to it will alter the behavior of this predicate. If
+ * {@code components} is empty, the returned predicate will always evaluate to
+ * {@code true}.
+ */
+ public static <T> Predicate<T> and(
+ Iterable<? extends Predicate<? super T>> components) {
+ return new AndPredicate<T>(components);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if each of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a false
+ * predicate is found. It does not defensively copy the array passed in, so
+ * future changes to it will alter the behavior of this predicate. If
+ * {@code components} is empty, the returned predicate will always evaluate to
+ * {@code true}.
+ */
+ public static <T> Predicate<T> and(Predicate<? super T>... components) {
+ return and(Arrays.asList(components));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both of its
+ * components evaluate to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as a false
+ * predicate is found.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Predicate<T> and(Predicate<? super T> first,
+ Predicate<? super T> second) {
+ return and(Arrays.<Predicate<? super T>> asList(first, second));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if any one of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as as soon as a
+ * true predicate is found. It does not defensively copy the iterable passed
+ * in, so future changes to it will alter the behavior of this predicate. If
+ * {@code components} is empty, the returned predicate will always evaluate to
+ * {@code false}.
+ */
+ public static <T> Predicate<T> or(
+ Iterable<? extends Predicate<? super T>> components) {
+ return new OrPredicate<T>(components);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if any one of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as as soon as a
+ * true predicate is found. It does not defensively copy the array passed in,
+ * so future changes to it will alter the behavior of this predicate. If
+ * {@code components} is empty, the returned predicate will always evaluate to
+ * {@code false}.
+ */
+ public static <T> Predicate<T> or(Predicate<? super T>... components) {
+ return or(Arrays.asList(components));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if either of its
+ * components evaluates to {@code true}. The components are evaluated in
+ * order, and evaluation will be "short-circuited" as soon as as soon as a
+ * true predicate is found.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Predicate<T> or(Predicate<? super T> first,
+ Predicate<? super T> second) {
+ return or(Arrays.<Predicate<? super T>> asList(first, second));
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object being
+ * tested {@code equals()} the given target or both are null.
+ */
+ public static <T> Predicate<T> isEqualTo(@Nullable T target) {
+ // TODO: Change signature to return Predicate<Object>.
+ return (target == null)
+ ? Predicates.<T>isNull()
+ : new IsEqualToPredicate<T>(target);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object being
+ * tested refers to the same object as the given target or both are null.
+ */
+ public static Predicate<Object> isSameAs(@Nullable Object target) {
+ return (target == null)
+ ? Predicates.isNull()
+ : new IsSameAsPredicate(target);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if the object reference
+ * being tested is a member of the given collection. It does not defensively
+ * copy the collection passed in, so future changes to it will alter the
+ * behavior of the predicate.
+ *
+ * @param target the collection that may contain the function input
+ */
+ public static <T> Predicate<T> in(Collection<?> target) {
+ return new InPredicate<T>(target);
+ }
+
+ /**
+ * Returns the composition of a function and a predicate. For every {@code x},
+ * the generated predicate returns {@code predicate(function(x))}.
+ *
+ * @return the composition of the provided function and predicate
+ */
+ public static <A, B> Predicate<A> compose(
+ Predicate<? super B> predicate,
+ Function<? super A, ? extends B> function) {
+ return new CompositionPredicate<A, B>(predicate, function);
+ }
+
+ /** @see Predicates#alwaysTrue() */
+ // enum singleton pattern
+ private enum AlwaysTruePredicate implements Predicate<Object> {
+ INSTANCE;
+
+ public boolean apply(Object o) {
+ return true;
+ }
+ @Override public String toString() {
+ return "AlwaysTrue";
+ }
+ }
+
+ /** @see Predicates#alwaysFalse() */
+ // enum singleton pattern
+ private enum AlwaysFalsePredicate implements Predicate<Object> {
+ INSTANCE;
+
+ public boolean apply(Object o) {
+ return false;
+ }
+ @Override public String toString() {
+ return "AlwaysFalse";
+ }
+ }
+
+ /** @see Predicates#not(Predicate) */
+ private static class NotPredicate<T>
+ implements Predicate<T>, Serializable {
+ private final Predicate<? super T> predicate;
+
+ private NotPredicate(Predicate<? super T> predicate) {
+ this.predicate = checkNotNull(predicate);
+ }
+ public boolean apply(T t) {
+ return !predicate.apply(t);
+ }
+ @Override public int hashCode() {
+ return ~predicate.hashCode(); /* Invert all bits. */
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof NotPredicate<?>) {
+ NotPredicate<?> that = (NotPredicate<?>) obj;
+ return predicate.equals(that.predicate);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "Not(" + predicate.toString() + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#and(Iterable) */
+ private static class AndPredicate<T>
+ implements Predicate<T>, Serializable {
+ private final Iterable<? extends Predicate<? super T>> components;
+
+ private AndPredicate(Iterable<? extends Predicate<? super T>> components) {
+ this.components = checkContentsNotNull(components);
+ }
+ public boolean apply(T t) {
+ for (Predicate<? super T> predicate : components) {
+ if (!predicate.apply(t)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ @Override public int hashCode() {
+ int result = -1; /* Start with all bits on. */
+ for (Predicate<? super T> predicate : components) {
+ result &= predicate.hashCode();
+ }
+ return result;
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof AndPredicate<?>) {
+ AndPredicate<?> that = (AndPredicate<?>) obj;
+ return iterableElementsEqual(components, that.components);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "And(" + Join.join(",", components) + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#or(Iterable) */
+ private static class OrPredicate<T>
+ implements Predicate<T>, Serializable {
+ private final Iterable<? extends Predicate<? super T>> components;
+
+ private OrPredicate(Iterable<? extends Predicate<? super T>> components) {
+ this.components = checkContentsNotNull(components);
+ }
+ public boolean apply(T t) {
+ for (Predicate<? super T> predicate : components) {
+ if (predicate.apply(t)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ @Override public int hashCode() {
+ int result = 0; /* Start with all bits off. */
+ for (Predicate<? super T> predicate : components) {
+ result |= predicate.hashCode();
+ }
+ return result;
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof OrPredicate<?>) {
+ OrPredicate<?> that = (OrPredicate<?>) obj;
+ return iterableElementsEqual(components, that.components);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "Or(" + Join.join(",", components) + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#isEqualTo(Object) */
+ private static class IsEqualToPredicate<T>
+ implements Predicate<T>, Serializable {
+ private final T target;
+
+ private IsEqualToPredicate(T target) {
+ this.target = target;
+ }
+ public boolean apply(T t) {
+ return target.equals(t);
+ }
+ @Override public int hashCode() {
+ return target.hashCode();
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof IsEqualToPredicate) {
+ IsEqualToPredicate<?> that = (IsEqualToPredicate<?>) obj;
+ return target.equals(that.target);
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "IsEqualTo(" + target + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#isSameAs(Object) */
+ private static class IsSameAsPredicate
+ implements Predicate<Object>, Serializable {
+ private final Object target;
+
+ private IsSameAsPredicate(Object target) {
+ this.target = target;
+ }
+ public boolean apply(Object o) {
+ return target == o;
+ }
+ @Override public int hashCode() {
+ return target.hashCode();
+ }
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof IsSameAsPredicate) {
+ IsSameAsPredicate that = (IsSameAsPredicate) obj;
+ return target == that.target;
+ }
+ return false;
+ }
+ @Override public String toString() {
+ return "IsSameAs(" + target + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#isNull() */
+ // enum singleton pattern
+ private enum IsNullPredicate implements Predicate<Object> {
+ INSTANCE;
+
+ public boolean apply(Object o) {
+ return o == null;
+ }
+ @Override public String toString() {
+ return "IsNull";
+ }
+ }
+
+ /** @see Predicates#notNull() */
+ // enum singleton pattern
+ private enum NotNullPredicate implements Predicate<Object> {
+ INSTANCE;
+
+ public boolean apply(Object o) {
+ return o != null;
+ }
+ @Override public String toString() {
+ return "NotNull";
+ }
+ }
+
+ /** @see Predicates#in(Collection) */
+ private static class InPredicate<T>
+ implements Predicate<T>, Serializable {
+ private final Collection<?> target;
+
+ private InPredicate(Collection<?> target) {
+ this.target = checkNotNull(target);
+ }
+
+ public boolean apply(T t) {
+ try {
+ return target.contains(t);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof InPredicate<?>) {
+ InPredicate<?> that = (InPredicate<?>) obj;
+ return target.equals(that.target);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return target.hashCode();
+ }
+
+ @Override public String toString() {
+ return "In(" + target + ")";
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Predicates#compose(Predicate, Function) */
+ private static class CompositionPredicate<A, B>
+ implements Predicate<A>, Serializable {
+ final Predicate<? super B> p;
+ final Function<? super A, ? extends B> f;
+
+ private CompositionPredicate(
+ Predicate<? super B> p, Function<? super A, ? extends B> f) {
+ this.p = checkNotNull(p);
+ this.f = checkNotNull(f);
+ }
+
+ public boolean apply(A a) {
+ return p.apply(f.apply(a));
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof CompositionPredicate<?, ?>) {
+ CompositionPredicate<?, ?> that = (CompositionPredicate<?, ?>) obj;
+ return f.equals(that.f) && p.equals(that.p);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ /*
+ * TODO: To leave the door open for future enhancement, this
+ * calculation should be coordinated with the hashCode() method of the
+ * corresponding composition method in Functions. To construct the
+ * composition:
+ * predicate(function2(function1(x)))
+ *
+ * There are two different ways of composing it:
+ * compose(predicate, compose(function2, function1))
+ * compose(compose(predicate, function2), function1)
+ *
+ * It would be nice if these could be equal.
+ */
+ return f.hashCode() ^ p.hashCode();
+ }
+
+ @Override public String toString() {
+ return p.toString() + "(" + f.toString() + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Determines whether the two Iterables contain equal elements. More
+ * specifically, this method returns {@code true} if {@code iterable1} and
+ * {@code iterable2} contain the same number of elements and every element of
+ * {@code iterable1} is equal to the corresponding element of {@code
+ * iterable2}.
+ *
+ * <p>This is not a general-purpose method; it assumes that the iterations
+ * contain no {@code null} elements.
+ */
+ private static boolean iterableElementsEqual(
+ Iterable<?> iterable1, Iterable<?> iterable2) {
+ Iterator<?> iterator1 = iterable1.iterator();
+ Iterator<?> iterator2 = iterable2.iterator();
+ while (iterator1.hasNext()) {
+ if (!iterator2.hasNext()) {
+ return false;
+ }
+ if (!iterator1.next().equals(iterator2.next())) {
+ return false;
+ }
+ }
+ return !iterator2.hasNext();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/ReferenceType.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/ReferenceType.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/ReferenceType.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+/**
+ * Reference type. Used to specify what type of reference to keep to a
+ * referent.
+ *
+ * @see java.lang.ref.Reference
+ * @author Bob Lee
+ */
+public enum ReferenceType {
+
+ /**
+ * Prevents referent from being reclaimed by the garbage collector.
+ */
+ STRONG,
+
+ /**
+ * Referent reclaimed in an LRU fashion when the VM runs low on memory and
+ * no strong references exist.
+ *
+ * @see java.lang.ref.SoftReference
+ */
+ SOFT,
+
+ /**
+ * Referent reclaimed when no strong or soft references exist.
+ *
+ * @see java.lang.ref.WeakReference
+ */
+ WEAK,
+
+ /**
+ * Similar to weak references except the garbage collector doesn't actually
+ * reclaim the referent. More flexible alternative to finalization.
+ *
+ * @see java.lang.ref.PhantomReference
+ */
+ PHANTOM;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Supplier.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Supplier.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Supplier.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+/**
+ * A class that can supply objects of a single type. Semantically, this could
+ * be a factory, generator, builder, closure, or something else entirely. No
+ * guarantees are implied by this interface.
+ *
+ * @author Harry Heymann
+ */
+public interface Supplier<T> {
+ /**
+ * Retrieves an instance of the appropriate type. The returned object may or
+ * may not be a new instance, depending on the implementation.
+ *
+ * @return an instance of the appropriate type
+ */
+ public T get();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Suppliers.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Suppliers.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/Suppliers.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.base;
+
+import java.io.Serializable;
+
+/**
+ * Useful suppliers.
+ *
+ * @author Laurence Gonsalves
+ * @author Harry Heymann
+ */
+public final class Suppliers {
+ private Suppliers() {}
+
+ /**
+ * Returns a new supplier which is the composition of the provided function
+ * and supplier. In other words, the new supplier's value will be computed by
+ * retrieving the value from {@code first}, and then applying
+ * {@code function} to that value. Note that the resulting supplier will not
+ * call {@code first} or invoke {@code function} until it is called.
+ */
+ public static <F, T> Supplier<T> compose(
+ Function<? super F, ? extends T> function, Supplier<? extends F> first) {
+ return new SupplierComposition<F, T>(function, first);
+ }
+
+ private static class SupplierComposition<F, T>
+ implements Supplier<T>, Serializable {
+ private final Function<? super F, ? extends T> function;
+ private final Supplier<? extends F> first;
+
+ public SupplierComposition(Function<? super F, ? extends T> function,
+ Supplier<? extends F> first) {
+ this.function = function;
+ this.first = first;
+ }
+ public T get() {
+ return function.apply(first.get());
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a supplier which caches the instance retrieved during the first
+ * call to {@code get()} and returns that value on subsequent calls to
+ * {@code get()}. See:
+ * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>
+ *
+ * <p>The returned supplier will throw {@code CyclicDependencyException} if
+ * the call to {@link Supplier#get} tries to get its own value. The returned
+ * supplier is <i>not</i> thread-safe.
+ */
+ public static <T> Supplier<T> memoize(Supplier<T> delegate) {
+ return new MemoizingSupplier<T>(delegate);
+ }
+
+ private static class MemoizingSupplier<T>
+ implements Supplier<T>, Serializable {
+ private final Supplier<T> delegate;
+ private MemoizationState state = MemoizationState.NOT_YET;
+ private T value;
+
+ public MemoizingSupplier(Supplier<T> delegate) {
+ this.delegate = delegate;
+ }
+ public T get() {
+ switch (state) {
+ case NOT_YET:
+ state = MemoizationState.COMPUTING;
+ try {
+ value = delegate.get();
+ } finally {
+ state = MemoizationState.NOT_YET;
+ }
+ state = MemoizationState.DONE;
+ break;
+ case COMPUTING:
+ throw new CyclicDependencyException();
+ }
+ return value;
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private enum MemoizationState { NOT_YET, COMPUTING, DONE }
+
+ /**
+ * Exception thrown when a memoizing supplier tries to get its own value.
+ */
+ public static class CyclicDependencyException extends RuntimeException {
+ CyclicDependencyException() {
+ super("Cycle detected when invoking a memoizing supplier.");
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a supplier that always supplies {@code instance}.
+ */
+ public static <T> Supplier<T> ofInstance(@Nullable T instance) {
+ return new SupplierOfInstance<T>(instance);
+ }
+
+ private static class SupplierOfInstance<T>
+ implements Supplier<T>, Serializable {
+ private final T instance;
+
+ public SupplierOfInstance(T instance) {
+ this.instance = instance;
+ }
+ public T get() {
+ return instance;
+ }
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/package-info.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/package-info.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/base/package-info.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Miscellaneous common util classes and annotations.
+ */
+package org.richfaces.collections.base;
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterable.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterable.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterable.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+/**
+ * Provides an implementation of {@link Object#toString} for {@link Iterable}
+ * instances.
+ *
+ * @author Mike Bostock
+ */
+public abstract class AbstractIterable<E> implements Iterable<E> {
+ /**
+ * Returns a string representation of this iterable. The string representation
+ * consists of a list of the iterable's elements in the order they are
+ * returned by its iterator, enclosed in square brackets ("[]"). Adjacent
+ * elements are separated by the characters ", " (comma and space). Elements
+ * are converted to strings as by {@link String#valueOf(Object)}.
+ */
+ @Override public String toString() {
+ return Iterables.toString(this);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterator.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterator.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractIterator.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * This class provides a skeletal implementation of the {@code Iterator}
+ * interface, to make this interface easier to implement for certain types of
+ * data sources.
+ *
+ * <p>{@code Iterator} requires its implementations to support querying the
+ * end-of-data status without changing the iterator's state, using the {@link
+ * #hasNext} method. But many data sources, such as {@link
+ * java.io.Reader#read()}), do not expose this information; the only way to
+ * discover whether there is any data left is by trying to retrieve it. These
+ * types of data sources are ordinarily difficult to write iterators for. But
+ * using this class, one must implement only the {@link #computeNext} method,
+ * and invoke the {@link #endOfData} method when appropriate.
+ *
+ * <p>Another example is an iterator that skips over null elements in a backing
+ * iterator. This could be implemented as: <pre> {@code
+ *
+ * public static Iterator<String> skipNulls(final Iterator<String> in) {
+ * return new AbstractIterator<String>() {
+ * protected String computeNext() {
+ * while (in.hasNext()) {
+ * String s = in.next();
+ * if (s != null) {
+ * return s;
+ * }
+ * }
+ * return endOfData();
+ * }
+ * };
+ * }}</pre>
+ *
+ * This class supports iterators that include null elements. The {@link
+ * #remove()} method throws an {@link UnsupportedOperationException}, but the
+ * similar class {@link AbstractRemovableIterator} does support {@code remove}.
+ *
+ * @author Kevin Bourrillion
+ */
+public abstract class AbstractIterator<T> implements Iterator<T> {
+ private State state = State.NOT_READY;
+
+ private enum State {
+ /** We have computed the next element and haven't returned it yet. */
+ READY,
+
+ /** We haven't yet computed or have already returned the element. */
+ NOT_READY,
+
+ /** We have reached the end of the data and are finished. */
+ DONE,
+
+ /** We've suffered an exception and are kaput. */
+ FAILED,
+ }
+
+ private T next;
+
+ /**
+ * Returns the next element. <b>Note:</b> the implementation must call {@link
+ * #endOfData} when there are no elements left in the iteration. Failure to do
+ * so could result in an infinite loop.
+ *
+ * <p>The initial invocation of {@link #hasNext()} or {@link #next()} calls
+ * this method, as does the first invocation of {@code hasNext} or
+ * {@code next} following each successful call to {@code next}. Once the
+ * implementation either invokes {@code endOfData} or throws an exception,
+ * {@code computeNext} is guaranteed to never be called again.
+ *
+ * <p>If this method throws an exception, it will propagate outward to the
+ * {@code hasNext()} or {@code next()} invocation that invoked this method.
+ * Any further attempts to use the iterator will result in an {@link
+ * IllegalStateException}.
+ *
+ * @return the next element if there was one. If {@code endOfData} was called
+ * during execution, the return value will be ignored.
+ * @throws RuntimeException if any unrecoverable error happens. This exception
+ * will propagate outward to the {@code hasNext()}, {@code next()}, or
+ * {@code peek()} invocation that invoked this method. Any further
+ * attempts to use the iterator will result in an
+ * {@link IllegalStateException}.
+ */
+ protected abstract T computeNext();
+
+ /**
+ * Implementations of {@code computeNext} <b>must</b> invoke this method when
+ * there are no elements left in the iteration.
+ *
+ * @return {@code null}; a convenience so your {@link #computeNext}
+ * implementation can use the simple statement {@code return endOfData();}
+ */
+ protected final T endOfData() {
+ state = State.DONE;
+ return null;
+ }
+
+ public boolean hasNext() {
+ checkState(state != State.FAILED);
+ switch (state) {
+ case DONE:
+ return false;
+ case READY:
+ return true;
+ default:
+ }
+ return tryToComputeNext();
+ }
+
+ private boolean tryToComputeNext() {
+ state = State.FAILED; // temporary pessimism
+ next = computeNext();
+ if (state != State.DONE) {
+ state = State.READY;
+ return true;
+ }
+ return false;
+ }
+
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ state = State.NOT_READY;
+ return next;
+ }
+
+ /**
+ * Returns the next element in the iteration without advancing the iteration,
+ * according to the contract of {@link PeekingIterator#peek()}.
+ *
+ * <p>Implementations of {@code AbstractIterator} that wish to expose this
+ * functionality should implement {@code PeekingIterator}.
+ */
+ public T peek() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return next;
+ }
+
+ /**
+ * This method is not supported.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapBasedMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapBasedMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapBasedMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.InvalidObjectException;
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Basic implementation of {@code Multiset<E>} backed by an instance of {@code
+ * Map<E, AtomicInteger>}.
+ *
+ * <p>For serialization to work, the subclass must specify explicit {@code
+ * readObject} and {@code writeObject} methods.
+ *
+ * @author Kevin Bourrillion
+ */
+abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
+ implements Serializable {
+
+ // TODO: Replace AtomicInteger with a to-be-written IntegerHolder class for
+ // better performance.
+ private transient Map<E, AtomicInteger> backingMap;
+
+ /*
+ * Cache the size for efficiency. Using a long lets us avoid the need for
+ * overflow checking and ensures that size() will function correctly even if
+ * the multiset had once been larger than Integer.MAX_VALUE.
+ */
+ private transient long size;
+
+ /** Standard constructor. */
+ protected AbstractMapBasedMultiset(Map<E, AtomicInteger> backingMap) {
+ this.backingMap = checkNotNull(backingMap);
+ this.size = super.size();
+ }
+
+ protected Map<E, AtomicInteger> backingMap() {
+ return backingMap;
+ }
+
+ /** Used during deserialization only. The backing map must be empty. */
+ protected void setBackingMap(Map<E, AtomicInteger> backingMap) {
+ this.backingMap = backingMap;
+ }
+
+ // Required Implementations
+
+ private transient volatile EntrySet entrySet;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Invoking {@link Multiset.Entry#getCount} on an entry in the returned
+ * set always returns the current count of that element in the multiset, as
+ * opposed to the count at the time the entry was retrieved.
+ */
+ @Override public Set<Multiset.Entry<E>> entrySet() {
+ EntrySet result = entrySet;
+ if (result == null) {
+ entrySet = result = new EntrySet();
+ }
+ return result;
+ }
+
+ private class EntrySet extends AbstractSet<Multiset.Entry<E>> {
+ @Override public Iterator<Multiset.Entry<E>> iterator() {
+ final Iterator<Map.Entry<E, AtomicInteger>> backingEntries
+ = backingMap.entrySet().iterator();
+ return new Iterator<Multiset.Entry<E>>() {
+ Map.Entry<E, AtomicInteger> toRemove;
+
+ public boolean hasNext() {
+ return backingEntries.hasNext();
+ }
+
+ public Multiset.Entry<E> next() {
+ final Map.Entry<E, AtomicInteger> mapEntry = backingEntries.next();
+ toRemove = mapEntry;
+ return new AbstractMultisetEntry<E>() {
+ public E getElement() {
+ return mapEntry.getKey();
+ }
+ public int getCount() {
+ int count = mapEntry.getValue().get();
+ if (count == 0) {
+ AtomicInteger frequency = backingMap.get(getElement());
+ if (frequency != null) {
+ count = frequency.get();
+ }
+ }
+ return count;
+ }
+ };
+ }
+
+ public void remove() {
+ checkState(toRemove != null,
+ "no calls to next() since the last call to remove()");
+ size -= toRemove.getValue().getAndSet(0);
+ backingEntries.remove();
+ toRemove = null;
+ }
+ };
+ }
+
+ @Override public int size() {
+ return backingMap.size();
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+
+ // The following overrides are for better performance.
+
+ @Override public void clear() {
+ for (AtomicInteger frequency : backingMap.values()) {
+ frequency.set(0);
+ }
+ backingMap.clear();
+ size = 0L;
+ }
+
+ @Override public boolean contains(Object o) {
+ if (o instanceof Entry) {
+ Entry<?> entry = (Entry<?>) o;
+ int count = count(entry.getElement());
+ return (count == entry.getCount()) && (count > 0);
+ }
+ return false;
+ }
+
+ @Override public boolean remove(Object o) {
+ if (contains(o)) {
+ Entry<?> entry = (Entry<?>) o;
+ AtomicInteger frequency = backingMap.remove(entry.getElement());
+ int numberRemoved = frequency.getAndSet(0);
+ size -= numberRemoved;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ // Optimizations - Query Operations
+
+ @Override public int size() {
+ return (int) Math.min(this.size, Integer.MAX_VALUE);
+ }
+
+ @Override public Iterator<E> iterator() {
+ return new MapBasedMultisetIterator();
+ }
+
+ /*
+ * Not subclassing AbstractMultiset$MultisetIterator because next() needs to
+ * retrieve the Map.Entry<E, AtomicInteger> entry, which can then be used for
+ * a more efficient remove() call.
+ */
+ private class MapBasedMultisetIterator implements Iterator<E> {
+ final Iterator<Map.Entry<E, AtomicInteger>> entryIterator;
+ Map.Entry<E, AtomicInteger> currentEntry;
+ int occurrencesLeft;
+ boolean canRemove;
+
+ MapBasedMultisetIterator() {
+ this.entryIterator = backingMap.entrySet().iterator();
+ }
+
+ public boolean hasNext() {
+ return occurrencesLeft > 0 || entryIterator.hasNext();
+ }
+
+ public E next() {
+ if (occurrencesLeft == 0) {
+ currentEntry = entryIterator.next();
+ occurrencesLeft = currentEntry.getValue().get();
+ }
+ occurrencesLeft--;
+ canRemove = true;
+ return currentEntry.getKey();
+ }
+
+ public void remove() {
+ checkState(canRemove,
+ "no calls to next() since the last call to remove()");
+ int frequency = currentEntry.getValue().get();
+ if (frequency <= 0) {
+ throw new ConcurrentModificationException();
+ }
+ if (currentEntry.getValue().addAndGet(-1) == 0) {
+ entryIterator.remove();
+ }
+ size--;
+ canRemove = false;
+ }
+ }
+
+ @Override public int count(@Nullable Object element) {
+ AtomicInteger frequency = backingMap.get(element);
+ return (frequency == null) ? 0 : frequency.get();
+ }
+
+ // Optional Operations - Modification Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalArgumentException if the call would result in more than
+ * {@link Integer#MAX_VALUE} occurrences of {@code element} in this
+ * multiset.
+ */
+ @Override public boolean add(@Nullable E element, int occurrences) {
+ if (occurrences == 0) {
+ return false;
+ }
+ checkArgument(
+ occurrences > 0, "occurrences cannot be negative: %s", occurrences);
+ AtomicInteger frequency = backingMap.get(element);
+ if (frequency == null) {
+ backingMap.put(element, new AtomicInteger(occurrences));
+ } else {
+ long newCount = (long) frequency.get() + (long) occurrences;
+ checkArgument(newCount <= Integer.MAX_VALUE,
+ "too many occurrences: %s", newCount);
+ frequency.getAndAdd(occurrences);
+ }
+ size += occurrences;
+ return true;
+ }
+
+ @Override public int remove(@Nullable Object element, int occurrences) {
+ if (occurrences == 0) {
+ return 0;
+ }
+ checkArgument(
+ occurrences > 0, "occurrences cannot be negative: %s", occurrences);
+ AtomicInteger frequency = backingMap.get(element);
+ if (frequency == null) {
+ return 0;
+ }
+
+ int numberRemoved;
+ if (frequency.get() > occurrences) {
+ numberRemoved = occurrences;
+ } else {
+ numberRemoved = frequency.get();
+ backingMap.remove(element);
+ }
+
+ frequency.addAndGet(-numberRemoved);
+ size -= numberRemoved;
+ return numberRemoved;
+ }
+
+ @Override public int removeAllOccurrences(@Nullable Object element) {
+ return removeAllOccurrences(element, backingMap);
+ }
+
+ private int removeAllOccurrences(@Nullable Object element,
+ Map<E, AtomicInteger> map) {
+ AtomicInteger frequency = map.remove(element);
+ if (frequency == null) {
+ return 0;
+ }
+ int numberRemoved = frequency.getAndSet(0);
+ size -= numberRemoved;
+ return numberRemoved;
+ }
+
+ // Views
+
+ @Override protected Set<E> createElementSet() {
+ return new MapBasedElementSet(backingMap);
+ }
+
+ class MapBasedElementSet extends ForwardingSet<E> {
+ /**
+ * This mapping is the usually the same as {@code backingMap}, but can
+ * be a submap in some implementations.
+ */
+ private final Map<E, AtomicInteger> map;
+ private final Set<E> delegate;
+
+ MapBasedElementSet(Map<E, AtomicInteger> map) {
+ this.map = map;
+ delegate = map.keySet();
+ }
+
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+
+ // TODO: a way to not have to write this much code?
+
+ @Override public Iterator<E> iterator() {
+ final Iterator<Map.Entry<E, AtomicInteger>> entries
+ = map.entrySet().iterator();
+ return new Iterator<E>() {
+ Map.Entry<E, AtomicInteger> toRemove;
+
+ public boolean hasNext() {
+ return entries.hasNext();
+ }
+
+ public E next() {
+ toRemove = entries.next();
+ return toRemove.getKey();
+ }
+
+ public void remove() {
+ checkState(toRemove != null,
+ "no calls to next() since the last call to remove()");
+ size -= toRemove.getValue().getAndSet(0);
+ entries.remove();
+ toRemove = null;
+ }
+ };
+ }
+
+ @Override public boolean remove(Object element) {
+ return removeAllOccurrences(element, map) != 0;
+ }
+
+ @Override public boolean removeAll(Collection<?> elementsToRemove) {
+ return Iterators.removeAll(iterator(), elementsToRemove);
+ }
+
+ @Override public boolean retainAll(Collection<?> elementsToRetain) {
+ return Iterators.retainAll(iterator(), elementsToRetain);
+ }
+
+ @Override public void clear() {
+ if (map == backingMap) {
+ AbstractMapBasedMultiset.this.clear();
+ } else {
+ Iterator<E> i = iterator();
+ while (i.hasNext()) {
+ i.next();
+ i.remove();
+ }
+ }
+ }
+
+ public Map<E, AtomicInteger> getMap() {
+ return map;
+ }
+ }
+
+ /** Don't allow default serialization. */
+ protected void readObjectNoData() throws InvalidObjectException {
+ throw new InvalidObjectException("Stream data required");
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapEntry.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapEntry.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMapEntry.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Objects;
+
+import java.util.Map.Entry;
+
+/**
+ * Implementation of the {@code equals}, {@code hashCode}, and {@code toString}
+ * methods of {@code Entry}.
+ *
+ * @author Jared Levy
+ */
+public abstract class AbstractMapEntry<K, V> implements Entry<K, V> {
+
+ public abstract K getKey();
+
+ public abstract V getValue();
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation throws an {@link UnsupportedOperationException}.
+ * Override this method to support mutable map entries.
+ */
+ public V setValue(V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Indicates whether an object equals this entry, following the behavior
+ * specified in {@link Entry#equals}.
+ */
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Entry)) {
+ return false;
+ }
+ Entry<?, ?> e = (Entry<?, ?>) o;
+ return Objects.equal(e.getKey(), getKey())
+ && Objects.equal(e.getValue(), getValue());
+ }
+
+ /**
+ * Return this entry's hash code, following the behavior specified in
+ * {@link Entry#hashCode}.
+ */
+ @Override public int hashCode() {
+ K k = getKey();
+ V v = getValue();
+ return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
+ }
+
+ /**
+ * Returns a string representation of the form <code>{key}={value}</code>.
+ */
+ @Override public String toString() {
+ return getKey() + "=" + getValue();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Objects;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * This class provides a skeletal implementation of the {@link Multiset}
+ * interface. A new multiset implementation can be created easily by extending
+ * this class and implementing the {@link Multiset#entrySet()} method, plus
+ * optionally overriding {@link #add(Object, int)} and
+ * {@link #remove(Object, int)} to enable modifications to the multiset.
+ *
+ * <p>The {@link #contains}, {@link #containsAll}, {@link #count}, and
+ * {@link #size} implementations all iterate across the set returned by
+ * {@link Multiset#entrySet()}, as do many methods acting on the set returned by
+ * {@link #elementSet}. Override those methods for better performance.
+ *
+ * @author Kevin Bourrillion
+ */
+public abstract class AbstractMultiset<E> extends AbstractCollection<E>
+ implements Multiset<E> {
+ public abstract Set<Entry<E>> entrySet();
+
+ // Query Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation iterates across {@link Multiset#entrySet()} and
+ * sums the counts of the entries.
+ */
+ @Override public int size() {
+ long sum = 0L;
+ for (Entry<E> entry : entrySet()) {
+ sum += entry.getCount();
+ }
+ return (int) Math.min(sum, Integer.MAX_VALUE);
+ }
+
+ @Override public boolean isEmpty() {
+ return entrySet().isEmpty();
+ }
+
+ /**
+ * Returns {@code true} if this collection contains the specified element.
+ *
+ * <p>This implementation checks whether {@link #elementSet} contains the
+ * element.
+ */
+ @Override public boolean contains(@Nullable Object element) {
+ return elementSet().contains(element);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation usually invokes methods of the
+ * {@link Multiset#entrySet()} iterator. However, the iterator's
+ * {@code remove} method sometimes calls the multiset's {@code remove}.
+ */
+ @Override public Iterator<E> iterator() {
+ return new MultisetIterator();
+ }
+
+ private class MultisetIterator implements Iterator<E> {
+ private final Iterator<Entry<E>> entryIterator;
+ private Entry<E> currentEntry;
+ /** Count of subsequent elements equal to current element */
+ private int laterCount;
+ /** Count of all elements equal to current element */
+ private int totalCount;
+ private boolean canRemove;
+
+ MultisetIterator() {
+ this.entryIterator = entrySet().iterator();
+ }
+
+ public boolean hasNext() {
+ return laterCount > 0 || entryIterator.hasNext();
+ }
+
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ if (laterCount == 0) {
+ currentEntry = entryIterator.next();
+ totalCount = laterCount = currentEntry.getCount();
+ }
+ laterCount--;
+ canRemove = true;
+ return currentEntry.getElement();
+ }
+
+ public void remove() {
+ checkState(canRemove,
+ "no calls to next() since the last call to remove()");
+ if (totalCount == 1) {
+ entryIterator.remove();
+ } else {
+ AbstractMultiset.this.remove(currentEntry.getElement());
+ }
+ totalCount--;
+ canRemove = false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation iterates across {@link Multiset#entrySet()} and
+ * sums the count of all entries.
+ */
+ public int count(Object element) {
+ for (Entry<E> entry : entrySet()) {
+ if (Objects.equal(entry.getElement(), element)) {
+ return entry.getCount();
+ }
+ }
+ return 0;
+ }
+
+ // Modification Operations
+
+ /**
+ * Ensures that this collection contains the specified element.
+ *
+ * <p>This implementation calls {@link #add(Object, int)} with one occurrence.
+ *
+ * @return {@code true} always
+ */
+ @Override public boolean add(@Nullable E element) {
+ add(element, 1);
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation always throws an
+ * {@link UnsupportedOperationException}. To support adding elements, override
+ * it.
+ */
+ public boolean add(E element, int occurrences) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Removes a single instance of the specified element from this collection, if
+ * it is present.
+ *
+ * <p>This implementation calls {@link #remove(Object, int)} with 1
+ * occurrence.
+ */
+ @Override public boolean remove(Object element) {
+ return remove(element, 1) == 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation always throws an
+ * {@link UnsupportedOperationException}. To support removing elements,
+ * override it.
+ */
+ public int remove(Object element, int occurrences) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation calls {@link #remove(Object, int)} with
+ * {@code Integer.MAX_VALUE} occurrences.
+ */
+ public int removeAllOccurrences(Object element) {
+ return remove(element, Integer.MAX_VALUE);
+ }
+
+ // Bulk Operations
+
+ /**
+ * Returns {@code true} if this multiset contains all of the elements in the
+ * specified collection.
+ *
+ * <p><b>Note:</b> this method does not take into account the occurrence
+ * count of an element in the two collections; it may still return {@code
+ * true} even if {@code elements} contains several occurrences of an element
+ * and this multiset contains only one. This is no different than any other
+ * collection type like {@link List}, but it may be unexpected to the user of
+ * a multiset.
+ *
+ * <p>This implementation checks whether {@link #elementSet} contains the
+ * elements.
+ */
+ @Override public boolean containsAll(Collection<?> elements) {
+ return elementSet().containsAll(elements);
+ }
+
+ /**
+ * Adds all of the elements in the specified collection to this multiset.
+ *
+ * <p>If the collection being added is a multiset, this implementation
+ * iterates over that multiset's entry set to add the appropriate number of
+ * occurrences of each of its elements to this multiset. Otherwise, it calls
+ * {@link AbstractCollection#addAll}.
+ */
+ @Override public boolean addAll(Collection<? extends E> elementsToAdd) {
+ if (elementsToAdd.isEmpty()) {
+ return false;
+ }
+ if (elementsToAdd instanceof Multiset) {
+ @SuppressWarnings("unchecked")
+ Multiset<? extends E> that = (Multiset<? extends E>) elementsToAdd;
+ for (Entry<? extends E> entry : that.entrySet()) {
+ add(entry.getElement(), entry.getCount());
+ }
+ } else {
+ super.addAll(elementsToAdd);
+ }
+ return true;
+ }
+
+ /**
+ * Removes all of this multiset's elements that are also contained in the
+ * specified collection.
+ *
+ * <p>This implementation iterates over the elements in the collection or, if
+ * {@code elementsToRemove} is a multiset, the elements in its element set,
+ * and calls {@link #removeAllOccurrences} on each element. In some cases,
+ * this approach has better performance than
+ * {@link AbstractCollection#removeAll}.
+ */
+ @Override public boolean removeAll(Collection<?> elementsToRemove) {
+ Iterable<?> iterable = (elementsToRemove instanceof Multiset)
+ ? ((Multiset<?>) elementsToRemove).elementSet() : elementsToRemove;
+
+ boolean modified = false;
+ for (Object element : iterable) {
+ if (removeAllOccurrences(element) != 0) {
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Retains only the elements in this multiset that are contained in the
+ * specified collection.
+ *
+ * <p>This implementation iterates over {@link #entrySet()}, checking each
+ * entry's element to see if it's contained in the provided collection.
+ * If it's not found, the {@code remove} method of the entry set's
+ * iterator is invoked. In some cases, this approach has better performance
+ * than {@link AbstractCollection#removeAll}.
+ */
+ @Override public boolean retainAll(Collection<?> elementsToRetain) {
+ checkNotNull(elementsToRetain);
+ Iterator<Entry<E>> entries = entrySet().iterator();
+ boolean modified = false;
+ while (entries.hasNext()) {
+ Entry<E> entry = entries.next();
+ if (!elementsToRetain.contains(entry.getElement())) {
+ entries.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Removes all of the elements from this multiset.
+ *
+ * <p>This implementation calls {@code clear} on {@link Multiset#entrySet()}.
+ */
+ @Override public void clear() {
+ entrySet().clear();
+ }
+
+ // Views
+
+ private transient volatile Set<E> elementSet;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned set's methods are implemented by calling
+ * {@link Multiset#entrySet()} methods.
+ */
+ public Set<E> elementSet() {
+ Set<E> result = elementSet;
+ if (result == null) {
+ elementSet = result = createElementSet();
+ }
+ return result;
+ }
+
+ /**
+ * Creates a new instance of this multiset's element set, which will be
+ * returned by {@link #elementSet}.
+ */
+ protected Set<E> createElementSet() {
+ return new ElementSet();
+ }
+
+ private class ElementSet extends AbstractSet<E> {
+ @Override public Iterator<E> iterator() {
+ final Iterator<Entry<E>> entryIterator = entrySet().iterator();
+ return new Iterator<E>() {
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ public E next() {
+ return entryIterator.next().getElement();
+ }
+ public void remove() {
+ entryIterator.remove();
+ }
+ };
+ }
+ @Override public int size() {
+ return entrySet().size();
+ }
+ }
+
+ // Object methods
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation returns {@code true} if {@code other} is a multiset
+ * of the same size and if, for each element, the two multisets have the same
+ * count.
+ */
+ @Override public boolean equals(@Nullable Object other) {
+ if (other instanceof Multiset) {
+ Multiset<?> that = (Multiset<?>) other;
+ /*
+ * We can't simply check whether the entry sets are equal, since that
+ * approach fails when a TreeMultiset has a comparator that returns 0
+ * when passed unequal elements.
+ */
+
+ if (this.size() != that.size()) {
+ return false;
+ }
+
+ for (Entry<?> entry : that.entrySet()) {
+ if (count(entry.getElement()) != entry.getCount()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation returns the hash code of {@link
+ * Multiset#entrySet()}.
+ */
+ @Override public int hashCode() {
+ return entrySet().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This implementation returns the result of invoking {@code toString} on
+ * {@link Multiset#entrySet()}.
+ */
+ @Override public String toString() {
+ return entrySet().toString();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultisetEntry.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultisetEntry.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractMultisetEntry.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Objects;
+import org.richfaces.collections.collect.Multiset.Entry;
+
+/**
+ * Implementation of the {@code equals}, {@code hashCode}, and {@code toString}
+ * methods of {@link Entry}.
+ *
+ * @author Mike Bostock
+ */
+public abstract class AbstractMultisetEntry<E> implements Entry<E> {
+ /**
+ * Indicates whether an object equals this entry, following the behavior
+ * specified in {@link Entry#equals}.
+ */
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Entry)) {
+ return false;
+ }
+ Entry<?> e = (Entry<?>) o;
+ return Objects.equal(e.getElement(), getElement())
+ && (e.getCount() == getCount());
+ }
+
+ /**
+ * Return this entry's hash code, following the behavior specified in
+ * {@link Entry#hashCode}.
+ */
+ @Override public int hashCode() {
+ E e = getElement();
+ return ((e == null) ? 0 : e.hashCode()) ^ getCount();
+ }
+
+ /**
+ * Returns a string representation of this multiset entry. The string
+ * representation consists of the associated element if the associated count
+ * is one, and otherwise the associated element followed by the characters " x
+ * " (space, x and space) followed by the count. Elements and counts are
+ * converted to strings as by {@code String.valueOf}.
+ */
+ @Override public String toString() {
+ String text = String.valueOf(getElement());
+ int n = getCount();
+ return (n == 1) ? text : (text + " x " + n);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractRemovableIterator.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractRemovableIterator.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/AbstractRemovableIterator.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+/**
+ * A specialization of {@code AbstractIterator} for data sources which can
+ * handle arbitrary removal by element, concurrently with iteration. Subclasses
+ * must implement both the {@link AbstractIterator#computeNext} and {@link
+ * #remove(Object)} methods.
+ *
+ * @author Kevin Bourrillion
+ */
+public abstract class AbstractRemovableIterator<T> extends AbstractIterator<T> {
+ private T elementToRemove;
+ private boolean canRemove;
+
+ /** Removes {@code element} from the backing data source. */
+ protected abstract void remove(T element);
+
+ @Override public T next() {
+ T element = super.next();
+ canRemove = true;
+ elementToRemove = element;
+ return element;
+ }
+
+ /**
+ * Removes from the underlying collection the last element returned by the
+ * iterator.
+ */
+ @Override public void remove() {
+ checkState(canRemove, "no calls to next() since the last call to remove()");
+ try {
+ remove(elementToRemove);
+ } finally {
+ elementToRemove = null;
+ canRemove = false;
+ }
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ArrayListMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ArrayListMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ArrayListMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Implementation of {@code Multimap} that uses an {@code ArrayList} to store
+ * the values for a given key. A {@link HashMap} associates each key with an
+ * {@link ArrayList} of values.
+ *
+ * <p>When iterating through the collections supplied by this class, the
+ * ordering of values for a given key agrees with the order in which the values
+ * were added.
+ *
+ * <p>This multimap allows duplicate key-value pairs. After adding a new
+ * key-value pair equal to an existing key-value pair, the {@code
+ * ArrayListMultimap} will contain entries for both the new value and the old
+ * value.
+ *
+ * <p>Keys and values may be null. All optional multimap methods are supported,
+ * and all returned views are modifiable.
+ *
+ * <p>This class is not threadsafe when any concurrent operations update the
+ * multimap. Concurrent read operations will work correctly. To allow concurrent
+ * update operations, wrap your multimap with a call to {@link
+ * Multimaps#synchronizedListMultimap}.
+ *
+ * @author Jared Levy
+ */
+public final class ArrayListMultimap<K, V> extends StandardListMultimap<K, V> {
+ // Default from ArrayList
+ /*@VisibleForTesting*/ static final int DEFAULT_CAPACITY = 10;
+
+ /*@VisibleForTesting*/ transient int initialListCapacity;
+
+ /** Constructs an empty {@code ArrayListMultimap}. */
+ public ArrayListMultimap() {
+ super(new HashMap<K, Collection<V>>());
+ initialListCapacity = DEFAULT_CAPACITY;
+ }
+
+ /**
+ * Constructs an empty {@code ArrayListMultimap} with the expected number of
+ * distinct keys and the expected number of values per distinct key.
+ *
+ * @param distinctKeys the expected number of distinct keys
+ * @param valuesPerKey the expected number of values per distinct key
+ * @throws IllegalArgumentException if either argument is negative
+ */
+ public ArrayListMultimap(int distinctKeys, int valuesPerKey) {
+ super(new HashMap<K, Collection<V>>(Maps.capacity(distinctKeys)));
+ checkArgument(valuesPerKey >= 0);
+ initialListCapacity = valuesPerKey;
+ }
+
+ /**
+ * Constructs an {@code ArrayListMultimap} with the same mappings as the
+ * specified {@code Multimap}.
+ */
+ public ArrayListMultimap(Multimap<? extends K, ? extends V> multimap) {
+ this(multimap.keySet().size(),
+ (multimap instanceof ArrayListMultimap) ?
+ ((ArrayListMultimap<?, ?>) multimap).initialListCapacity :
+ DEFAULT_CAPACITY);
+ putAll(multimap);
+ }
+
+ /**
+ * Creates a new empty {@code ArrayList} to hold the collection of values for
+ * an arbitrary key.
+ */
+ @Override List<V> createCollection() {
+ return new ArrayList<V>(initialListCapacity);
+ }
+
+ /**
+ * Reduces the memory used by this {@code ArrayListMultimap}, if feasible.
+ */
+ public void trimToSize() {
+ for (Collection<V> collection : backingMap().values()) {
+ ArrayList<V> arrayList = (ArrayList<V>) collection;
+ arrayList.trimToSize();
+ }
+ }
+
+ /**
+ * @serialData initial list capacity, number of distinct keys, and then for
+ * each distinct key: the key, number of values for that key, and the
+ * key's values
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeInt(initialListCapacity);
+ Serialization.writeMultimap(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setMap(new HashMap<K, Collection<V>>());
+ initialListCapacity = stream.readInt();
+ Serialization.populateMultimap(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/BiMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/BiMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/BiMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A bimap (or "bidirectional map") is a map that preserves the uniqueness of
+ * its values as well as that of its keys. This constraint enables bimaps to
+ * support an "inverse view", which is another bimap containing the same entries
+ * as this bimap but with reversed keys and values.
+ *
+ * @author Kevin Bourrillion
+ */
+public interface BiMap<K, V> extends Map<K, V> {
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalArgumentException if the given value is already bound to a
+ * different key in this bimap. The bimap will remain unmodified in this
+ * event. To avoid this exception, call {@link #forcePut} instead.
+ */
+ V put(K key, V value);
+
+ /**
+ * An alternate form of {@code put} that silently removes any existing entry
+ * with the value {@code value} before proceeding with the {@link #put}
+ * operation. If the bimap previously contained the provided key-value
+ * mapping, this method has no effect.
+ *
+ * <p>Note that a successful call to this method could cause the size of the
+ * bimap to increase by one, stay the same, or even decrease by one.
+ *
+ * <p><b>Warning</b>: If an existing entry with this value is removed, the key
+ * for that entry is discarded and not returned.
+ *
+ * @param key the key with which the specified value is to be associated
+ * @param value the value to be associated with the specified key
+ * @return the value which was previously associated with the key, which may
+ * be {@code null}, or {@code null} if there was no previous entry
+ */
+ V forcePut(K key, V value);
+
+ // Bulk Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p><b>Warning:</b> the results of calling this method may vary depending on
+ * the iteration order of {@code map}.
+ *
+ * @throws IllegalArgumentException if an attempt to {@code put} any
+ * entry fails. Note that some map entries may have been added to the
+ * bimap before the exception was thrown.
+ */
+ void putAll(Map<? extends K, ? extends V> map);
+
+ // Views
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a bimap has unique values, this method returns a {@link Set},
+ * instead of the {@link java.util.Collection} specified in the {@link Map}
+ * interface.
+ */
+ Set<V> values();
+
+ /**
+ * Returns the inverse view of this bimap, which maps each of this bimap's
+ * values to its associated key. The two bimaps are backed by the same data;
+ * any changes to one will appear in the other.
+ *
+ * <p><b>Note:</b>There is no guaranteed correspondence between the iteration
+ * order of a bimap and that of its inverse.
+ *
+ * @return the inverse view of this bimap
+ */
+ BiMap<V, K> inverse();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ClassToInstanceMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ClassToInstanceMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ClassToInstanceMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Map;
+
+/**
+ * A map, each entry of which maps a Java
+ * <a href="http://tinyurl.com/2cmwkz">raw type</a> to an instance of that type.
+ * In addition to implementing {@code Map}, the additional type-safe operations
+ * {@link #putInstance} and {@link #getInstance} are available.
+ *
+ * <p>Like any other {@code Map<Class, Object>}, this map may contain entries
+ * for primitive types, and a primitive type and its corresponding wrapper type
+ * may map to different values.
+ *
+ * @param <B> the common supertype that all entries must share; often this is
+ * simply {@link Object}
+ *
+ * @author Kevin Bourrillion
+ */
+public interface ClassToInstanceMap<B> extends Map<Class<? extends B>, B> {
+ /**
+ * Returns the value the specified class is mapped to, or {@code null} if no
+ * entry for this class is present. This will only return a value that was
+ * bound to this specific class, not a value that may have been bound to a
+ * subtype.
+ */
+ <T extends B> T getInstance(Class<T> type);
+
+ /**
+ * Maps the specified class to the specified value. Does <i>not</i> associate
+ * this value with any of the class's supertypes.
+ *
+ * @return the value previously associated with this class (possibly {@code
+ * null}), or {@code null} if there was no previous entry.
+ */
+ <T extends B> T putInstance(Class<T> type, @Nullable T value);
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Collections2.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Collections2.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Collections2.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import org.richfaces.collections.base.Predicate;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * Provides static methods for working with {@code Collection} instances.
+ *
+ * @author Chris Povirk
+ * @author Mike Bostock
+ * @author Jared Levy
+ */
+public final class Collections2 {
+ private Collections2() {}
+
+ /**
+ * Returns a limited {@link Collection} view of the given {@link Iterable}, or
+ * the {@code Iterable} itself if it is already a {@code Collection} (in which
+ * case the rest of this documentation does not apply). The returned
+ * collection is not appropriate for general use for a number of reasons.
+ * Instead, it exists to provide frequently desired methods for dealing with
+ * {@code Iterable} objects -- such as
+ * {@link Collection#removeAll(Collection)} -- through the familiar
+ * {@code Collection} interface. To treat the contents of an {@code Iterable}
+ * as a full-fledged, performant {@code Collection}, it is recommended that
+ * clients call a method like {@link ImmutableSet#copyOf(Iterable)} or
+ * {@link Iterables#addAll(Collection, Iterable)} to dump the contents of the
+ * {@code Iterable} into a standard {@code Collection}. For cases in which a
+ * view of the {@code Iterable} is required, {@code forIterable()} is
+ * available.
+ *
+ * <p>A number of limitations result from building on the {@code Iterable}
+ * interface. Notably, {@code size()}, {@code contains()}, and many other
+ * methods of the returned collection are O(n). The returned collection does
+ * not support the insertion of items. Removal of elements is supported if the
+ * underlying {@code Iterable} supports it, and all non-mutative operations
+ * are supported. Additionally, each method call on the returned collection
+ * calls {@link Iterable#iterator()} on the source {@code Iterable}. Thus, if
+ * you wish to call more than one method on the collection or to otherwise
+ * access the contents of the {@code Iterable} after calling a method, the
+ * {@code Iterable} must support the creation of multiple iterators.
+ *
+ * <p>{@link #equals(Object)} and {@link #hashCode()} are inherited from
+ * {@link Object}, as the returned {@code Collection} is not an implementation
+ * of any additional interface, such as {@link java.util.List} or
+ * {@link java.util.Set}.
+ *
+ * <p>The behavior of the returned collection's iterator in the face of
+ * concurrent structural modification of the returned collection or of the
+ * underlying {@code Iterable} is undefined, and no guarantee is made that the
+ * objects are fail-fast.
+ *
+ * <p><b>Usage Example</b>
+ *
+ * <pre>
+ * // Remove all instances of "foo" from an Iterable:
+ * Collections2.forIterable(iterable).removeAll(ImmutableSet.of("foo"));
+ * </pre>
+ */
+ public static <T> Collection<T> forIterable(final Iterable<T> iterable) {
+ checkNotNull(iterable);
+
+ if (iterable instanceof Collection) {
+ return (Collection<T>) iterable;
+ }
+
+ return new AbstractCollection<T>() {
+ @Override public Iterator<T> iterator() {
+ return iterable.iterator();
+ }
+
+ @Override public int size() {
+ return Iterables.size(iterable);
+ }
+
+ @Override public boolean isEmpty() {
+ return Iterables.isEmpty(iterable);
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+ };
+ }
+
+ /**
+ * Returns {@code true} if the collection {@code self} contains all of the
+ * elements in the collection {@code c}.
+ *
+ * <p>This method iterates over the specified collection {@code c}, checking
+ * each element returned by the iterator in turn to see if it is contained in
+ * the specified collection {@code self}. If all elements are so contained,
+ * {@code true} is returned, otherwise {@code false}.
+ *
+ * @param self a collection which might contain all elements in {@code c}
+ * @param c a collection whose elements might be contained by {@code self}
+ */
+ // TODO: Make public?
+ static boolean containsAll(Collection<?> self, Collection<?> c) {
+ checkNotNull(self);
+ for (Object o : c) {
+ if (!self.contains(o)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Converts an iterable into a collection. If the iterable is already a
+ * collection, it is returned. Otherwise, an {@link java.util.ArrayList} is
+ * created with the contents of the iterable in same iteration order.
+ */
+ static <E> Collection<E> toCollection(Iterable<E> iterable) {
+ return (iterable instanceof Collection)
+ ? (Collection<E>) iterable : Lists.newArrayList(iterable);
+ }
+
+ /**
+ * Returns the elements of {@code unfiltered} that satisfy a predicate. The
+ * returned collection is a live view of {@code unfiltered}; changes to one
+ * affect the other.
+ *
+ * <p>The resulting collection's iterator does not support {@code remove()},
+ * but all other collection methods are supported. The collection's
+ * {@code add()} and {@code addAll()} methods throw an
+ * {@link IllegalArgumentException} if an element that doesn't satisfy the
+ * predicate is provided. When methods such as {@code removeAll()} and
+ * {@code clear()} are called on the filtered collection, only elements that
+ * satisfy the filter will be removed from the underlying collection.
+ *
+ * <p>The returned collection isn't threadsafe or serializable, even if
+ * {@code unfiltered} is.
+ *
+ * <p>Many of the filtered collection's methods, such as {@code size()},
+ * iterate across every element in the underlying collection and determine
+ * which elements satisfy the filter. When a live view is <i>not</i> needed,
+ * it may be faster to copy the filtered collection and use the copy.
+ *
+ * <p>The {@code clear()}, {@code removeAll()}, and {@code retainAll()}
+ * methods all call {@link Iterator#remove()} on the underlying collection's
+ * iterator. Consequently, methods like the following throw an
+ * {@link UnsupportedOperationException}.
+ * <pre> Collections2.filter(Collections2.filter(collection, predicate1),
+ * predicate2)).clear();</pre>
+ * Instead, call
+ * {@link org.richfaces.collections.base.Predicates#and(Predicate, Predicate)} to
+ * combine the predicates and pass the combined predicate to this method.
+ *
+ */
+ public static <T> Collection<T> filter(
+ Collection<T> unfiltered, Predicate<? super T> predicate) {
+ return new FilteredCollection<T>(unfiltered, predicate);
+ }
+
+ static class FilteredCollection<T> implements Collection<T> {
+ private final Collection<T> unfiltered;
+ private final Predicate<? super T> predicate;
+
+ FilteredCollection(Collection<T> unfiltered,
+ Predicate<? super T> predicate) {
+ this.unfiltered = checkNotNull(unfiltered);
+ this.predicate = checkNotNull(predicate);
+ }
+
+ public boolean add(T element) {
+ checkArgument(predicate.apply(element));
+ return unfiltered.add(element);
+ }
+
+ public boolean addAll(Collection<? extends T> collection) {
+ for (T element : collection) {
+ checkArgument(predicate.apply(element));
+ }
+ return unfiltered.addAll(collection);
+ }
+
+ public void clear() {
+ Iterator<T> iterator = unfiltered.iterator();
+ while (iterator.hasNext()) {
+ T element = iterator.next();
+ if (predicate.apply(element)) {
+ iterator.remove();
+ }
+ }
+ }
+
+ // if a ClassCastException occurs, contains() returns false
+ @SuppressWarnings("unchecked")
+ public boolean contains(Object element) {
+ try {
+ return predicate.apply((T) element) && unfiltered.contains(element);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ public boolean containsAll(Collection<?> collection) {
+ for (Object element : collection) {
+ if (!contains(element)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean isEmpty() {
+ return !Iterators.any(unfiltered.iterator(), predicate);
+ }
+
+ public Iterator<T> iterator() {
+ return Iterators.filter(unfiltered.iterator(), predicate);
+ }
+
+ // if a ClassCastException occurs, remove() returns false
+ @SuppressWarnings("unchecked")
+ public boolean remove(Object element) {
+ try {
+ return predicate.apply((T) element) && unfiltered.remove(element);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ public boolean removeAll(Collection<?> collection) {
+ checkNotNull(collection);
+ boolean changed = false;
+ Iterator<T> iterator = unfiltered.iterator();
+ while (iterator.hasNext()) {
+ T element = iterator.next();
+ if (predicate.apply(element) && collection.contains(element)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ public boolean retainAll(Collection<?> collection) {
+ checkNotNull(collection);
+ boolean changed = false;
+ Iterator<T> iterator = unfiltered.iterator();
+ while (iterator.hasNext()) {
+ T element = iterator.next();
+ if (predicate.apply(element) && !collection.contains(element)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ public int size() {
+ return Iterators.size(iterator());
+ }
+
+ public Object[] toArray() {
+ // creating an ArrayList so filtering happens once
+ return Lists.newArrayList(iterator()).toArray();
+ }
+
+ public <T> T[] toArray(T[] array) {
+ return Lists.newArrayList(iterator()).toArray(array);
+ }
+
+ @Override public String toString() {
+ return Iterators.toString(iterator());
+ }
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Comparators.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Comparators.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Comparators.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,896 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkContentsNotNull;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import org.richfaces.collections.base.Function;
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Objects;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Standard comparators and utilities for creating and working with comparators.
+ *
+ * <p>Some of these methods return an {@link Ordering}, a serializable class
+ * that implements {@link Comparator} and includes many additional methods.
+ *
+ * <p>Several method signatures include {@code <C extends Comparable>} with a
+ * raw {@link Comparable}, instead of
+ * {@code <C extends Comparable<? super C>}. That's necessary to support classes
+ * defined without generics.
+ *
+ * @author Jared Levy
+ * @author Kevin Bourrillion
+ * @author Mike Bostock
+ */
+public final class Comparators {
+ private Comparators() {}
+
+ /**
+ * Returns a comparator that uses the natural ordering of the values. The
+ * comparator throws a {@link NullPointerException} when passed a null
+ * parameter.
+ */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ public static <T extends Comparable> Ordering<T> naturalOrder() {
+ return (Ordering<T>) NATURAL_ORDER;
+ }
+
+ /** @see #naturalOrder */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static final Ordering<Comparable> NATURAL_ORDER
+ = new NaturalOrdering();
+
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static class NaturalOrdering extends Ordering<Comparable> {
+ public int compare(Comparable left, Comparable right) {
+ checkNotNull(right); // later code throws NPE when only left is null
+ if (left == right) {
+ return 0;
+ }
+
+ /*
+ * compareTo() may throw a ClassCastException if the elements are not
+ * mutually comparable.
+ */
+ int result = left.compareTo(right);
+ return result;
+ }
+
+ // preserve singleton-ness, so equals() and hashCode() work correctly
+ private Object readResolve() {
+ return NATURAL_ORDER;
+ }
+
+ @Override public String toString() {
+ return "naturalOrder()";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a comparator that treats {@code null} as less than all other
+ * values and uses {@code comparator} to compare non-null values.
+ */
+ public static <T> Ordering<T> nullLeastOrder(Comparator<T> comparator) {
+ checkNotNull(comparator);
+ return new NullLeastOrdering<T>(comparator);
+ }
+
+ private static class NullLeastOrdering<T> extends NullHandlingOrdering<T> {
+ NullLeastOrdering(Comparator<T> comparator) {
+ super(comparator);
+ }
+
+ @Override int compareNullAndNonNull() {
+ return -1;
+ }
+
+ @Override public String toString() {
+ return "nullLeastOrder(" + comparator + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a comparator that uses the natural ordering of the values, but also
+ * handles null values, treating them as less than all other values.
+ */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ public static <T extends Comparable> Ordering<T> nullLeastOrder() {
+ return (Ordering<T>) NULL_LEAST_ORDER;
+ }
+
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static final Ordering<Comparable> NULL_LEAST_ORDER
+ = new NaturalNullLeastOrder();
+
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static class NaturalNullLeastOrder
+ extends NullLeastOrdering<Comparable> {
+ private NaturalNullLeastOrder() {
+ super(NATURAL_ORDER);
+ }
+
+ // preserve singleton-ness
+ private Object readResolve() {
+ return NULL_LEAST_ORDER;
+ }
+
+ @Override public String toString() {
+ return "nullLeastOrder()";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a comparator that treats {@code null} as greater than all other
+ * values and uses the given comparator to compare non-null values.
+ */
+ public static <T> Ordering<T> nullGreatestOrder(Comparator<T> comparator) {
+ checkNotNull(comparator);
+ return new NullGreatestOrdering<T>(comparator);
+ }
+
+ private static class NullGreatestOrdering<T> extends NullHandlingOrdering<T> {
+ NullGreatestOrdering(Comparator<T> comparator) {
+ super(comparator);
+ }
+
+ @Override int compareNullAndNonNull() {
+ return 1;
+ }
+
+ @Override public String toString() {
+ return "nullGreatestOrder(" + comparator + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a comparator that uses the natural ordering of the values, but also
+ * handles null values, treating them as greater than all other values.
+ */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ public static <T extends Comparable> Ordering<T> nullGreatestOrder() {
+ return (Ordering<T>) NULL_GREATEST_ORDER;
+ }
+
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static final Ordering<Comparable> NULL_GREATEST_ORDER
+ = new NaturalNullGreatestOrder();
+
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static class NaturalNullGreatestOrder
+ extends NullGreatestOrdering<Comparable> {
+ private NaturalNullGreatestOrder() {
+ super(NATURAL_ORDER);
+ }
+
+ // preserve singleton-ness
+ private Object readResolve() {
+ return NULL_GREATEST_ORDER;
+ }
+
+ @Override public String toString() {
+ return "nullGreatestOrder()";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private static abstract class NullHandlingOrdering<T> extends Ordering<T> {
+ final Comparator<T> comparator;
+
+ public NullHandlingOrdering(Comparator<T> comparator) {
+ this.comparator = comparator;
+ }
+
+ public int compare(T left, T right) {
+ if (left == right) {
+ return 0;
+ }
+ if (left == null) {
+ return compareNullAndNonNull();
+ }
+ if (right == null) {
+ return -compareNullAndNonNull();
+ }
+ return comparator.compare(left, right);
+ }
+
+ /**
+ * Returns the value this comparator should produce when comparing {@code
+ * null} to any non-null value (in that order).
+ */
+ abstract int compareNullAndNonNull();
+
+ @Override public boolean equals(Object object) {
+ if (object == null) {
+ return false;
+ }
+ if (object instanceof NullHandlingOrdering) {
+ NullHandlingOrdering<?> that = (NullHandlingOrdering<?>) object;
+ return (this.compareNullAndNonNull() == that.compareNullAndNonNull())
+ && this.comparator.equals(that.comparator);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return comparator.hashCode();
+ }
+ }
+
+ /**
+ * Returns a comparator which tries two comparators in order until a non-zero
+ * result is found, returning that result, and returning zero only if both
+ * comparators return zero.
+ *
+ * @param first the first comparator to invoke
+ * @param second the second comparator to invoke
+ * @see #compound(Iterable)
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Ordering<T> compound(Comparator<? super T> first,
+ Comparator<? super T> second) {
+ Comparator<T> firstT = (Comparator<T>) first;
+ Comparator<T> secondT = (Comparator<T>) second;
+ return compound(Arrays.asList(firstT, secondT));
+ }
+
+ /**
+ * Returns a comparator which tries three comparators in order until a
+ * non-zero result is found, returning that result, and returning zero only if
+ * all comparators return zero.
+ *
+ * @param first the first comparator to invoke
+ * @param second the second comparator to invoke
+ * @param third the third comparator to invoke
+ * @see #compound(Iterable)
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Ordering<T> compound(Comparator<? super T> first,
+ Comparator<? super T> second, Comparator<? super T> third) {
+ Comparator<T> firstT = (Comparator<T>) first;
+ Comparator<T> secondT = (Comparator<T>) second;
+ Comparator<T> thirdT = (Comparator<T>) third;
+ return compound(Arrays.asList(firstT, secondT, thirdT));
+ }
+
+ /**
+ * Returns a comparator which tries four comparators in order until a non-zero
+ * result is found, returning that result, and returning zero only if all
+ * comparators return zero.
+ *
+ * @param first the first comparator to invoke
+ * @param second the second comparator to invoke
+ * @param third the third comparator to invoke
+ * @param forth the fourth comparator to invoke
+ * @see #compound(Iterable)
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Ordering<T> compound(Comparator<? super T> first,
+ Comparator<? super T> second, Comparator<? super T> third,
+ Comparator<? super T> forth) {
+ Comparator<T> firstT = (Comparator<T>) first;
+ Comparator<T> secondT = (Comparator<T>) second;
+ Comparator<T> thirdT = (Comparator<T>) third;
+ Comparator<T> forthT = (Comparator<T>) forth;
+ return compound(Arrays.asList(firstT, secondT, thirdT, forthT));
+ }
+
+ /**
+ * Returns a comparator which tries each given comparator in order until a
+ * non-zero result is found, returning that result, and returning zero only if
+ * all comparators return zero.
+ *
+ * <p>Subsequent changes to the {@code rest} array do not affect the behavior
+ * of the returned comparator.
+ *
+ * @param first the first comparator to invoke
+ * @param second the second comparator to invoke
+ * @param third the third comparator to invoke
+ * @param forth the fourth comparator to invoke
+ * @param rest additional comparators to invoke as necessary
+ * @see #compound(Iterable)
+ */
+ @SuppressWarnings("unchecked") // TODO: check that this is right
+ public static <T> Ordering<T> compound(Comparator<? super T> first,
+ Comparator<? super T> second, Comparator<? super T> third,
+ Comparator<? super T> forth, Comparator<? super T>... rest) {
+ // TODO: is this really the best way? if so, explain why.
+ Comparator<T> firstT = (Comparator<T>) first;
+ Comparator<T> secondT = (Comparator<T>) second;
+ Comparator<T> thirdT = (Comparator<T>) third;
+ Comparator<T> forthT = (Comparator<T>) forth;
+ List<Comparator<T>> list = Lists.newArrayList(
+ firstT, secondT, thirdT, forthT);
+ list.addAll(Arrays.asList((Comparator<T>[]) rest));
+ return compound(list);
+ }
+
+ /**
+ * Returns a comparator which tries each given comparator in order until a
+ * non-zero result is found, returning that result, and returning zero only if
+ * all comparators return zero.
+ *
+ * <p>The returned comparator is a "view" of the specified {@code Iterable}
+ * instance; changes to the iterable will be reflected in the behavior of the
+ * returned comparator.
+ *
+ * <p><b>Warning:</b> Supplying an argument with undefined iteration order,
+ * such as a {@link java.util.HashSet}, will produce non-deterministic
+ * results.
+ *
+ * @param comparators the comparators to try in order
+ */
+ public static <T> Ordering<T> compound(
+ Iterable<? extends Comparator<? super T>> comparators) {
+ return new CompoundOrder<T>(comparators);
+ }
+
+ /** @see Comparators#compound(Iterable) */
+ static class CompoundOrder<T> extends Ordering<T> {
+ private final Iterable<? extends Comparator<? super T>> comparators;
+
+ CompoundOrder(Iterable<? extends Comparator<? super T>> comparators) {
+ this.comparators = checkContentsNotNull(comparators);
+ }
+
+ public int compare(T left, T right) {
+ if (left == right) {
+ return 0;
+ }
+ for (Comparator<? super T> comparator : comparators) {
+ int result = comparator.compare(left, right);
+ if (result != 0) {
+ return result;
+ }
+ }
+ return 0;
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object instanceof CompoundOrder) {
+ CompoundOrder<?> that = (CompoundOrder<?>) object;
+ return (this.comparators).equals(that.comparators);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return comparators.hashCode();
+ }
+
+ @Override public String toString() {
+ return "compound(" + comparators + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a comparator that compares any two items by applying a function to
+ * each of them and using the natural ordering of the results.
+ *
+ * @param function the function returning the value to compare. The function
+ * should never return {@code null}.
+ * @return the generated comparator
+ */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ public static <F, T extends Comparable> Ordering<F>
+ fromFunction(Function<F, T> function) {
+ return new TransformingNaturalOrder<F, T>(function);
+ }
+
+ /** @see Comparators#fromFunction(Function) */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ private static class TransformingNaturalOrder<F, T extends Comparable>
+ extends Ordering<F> {
+ private final Function<F, T> function;
+
+ TransformingNaturalOrder(Function<F, T> function) {
+ this.function = checkNotNull(function);
+ }
+
+ public int compare(F left, F right) {
+ T leftTransformed = function.apply(left);
+ T rightTransformed = function.apply(right);
+
+ /*
+ * Let this throw a ClassCastException if T is a bizarre Comparable that
+ * can't be compared to itself.
+ */
+ return leftTransformed.compareTo(rightTransformed);
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object instanceof TransformingNaturalOrder) {
+ TransformingNaturalOrder<?, ?> that
+ = (TransformingNaturalOrder<?, ?>) object;
+ return (this.function).equals(that.function);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return function.hashCode();
+ }
+
+ @Override public String toString() {
+ return "fromFunction(" + function + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a comparator that compares any two items by applying a function to
+ * each of them and using the supplied comparator to compare the results.
+ *
+ * @param function the function returning the value to compare
+ * @param comparator the comparator that receives the function output
+ * @return the generated comparator
+ */
+ public static <F, T> Ordering<F> fromFunction(
+ Function<F, T> function, Comparator<? super T> comparator) {
+ return new TransformingOrder<F, T>(function, comparator);
+ }
+
+ /** @see Comparators#fromFunction(Function,Comparator) */
+ private static class TransformingOrder<F, T> extends Ordering<F> {
+ private final Function<F, T> function;
+ private final Comparator<? super T> comparator;
+
+ TransformingOrder(
+ Function<F, T> function, Comparator<? super T> comparator) {
+ this.function = checkNotNull(function);
+ this.comparator = checkNotNull(comparator);
+ }
+
+ public int compare(F left, F right) {
+ return comparator.compare(function.apply(left), function.apply(right));
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object instanceof TransformingOrder) {
+ TransformingOrder<?, ?> that = (TransformingOrder<?, ?>) object;
+ return (this.function).equals(that.function)
+ && (this.comparator).equals(that.comparator);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return Objects.hashCode(function, comparator);
+ }
+
+ @Override public String toString() {
+ return "fromFunction(" + function + ", " + comparator + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * A comparator that compares objects by the natural ordering of their string
+ * representations as returned by {@code toString()}. It does not support null
+ * values.
+ *
+ * <p>TODO: Deprecate this in favor of {@link #toStringOrder}.
+ */
+ public static final Ordering<Object> STRING_FORM_ORDER = new ToStringOrder();
+
+ private static class ToStringOrder extends Ordering<Object> {
+ public int compare(Object o1, Object o2) {
+ return o1.toString().compareTo(o2.toString());
+ }
+
+ // preserve singleton-ness, so equals() and hashCode() work correctly
+ private Object readResolve() {
+ return STRING_FORM_ORDER;
+ }
+
+ @Override public String toString() {
+ return "toStringOrder()";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a comparator that compares objects by the natural ordering of their
+ * string representations as returned by {@code toString()}. It does not
+ * support null values.
+ */
+ @SuppressWarnings("unchecked") // casting STRING_FORM_ORDER
+ public static final <T> Ordering<T> toStringOrder() {
+ return (Ordering<T>) STRING_FORM_ORDER;
+ }
+
+ /**
+ * Returns the smaller of the two values, according to their natural ordering.
+ * If the values are equal, the first is returned.
+ *
+ * <p>To handle more than two values, call
+ * {@link Ordering#min(Object, Object, Object, Object...)} or
+ * {@link Ordering#min(Iterable)} on the {@link Ordering} returned by
+ * {@link Ordering#natural()}.
+ *
+ * @param a non-null value to compare, returned if less than or equal to b.
+ * @param b non-null value to compare.
+ * @throws ClassCastException if the parameters are not mutually comparable
+ * (for example, a string and an integer).
+ */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ public static <T extends Comparable> T min(T a, T b) {
+ /*
+ * Let this throw a ClassCastException if T is a bizarre Comparable that
+ * can't be compared to itself, as documented.
+ */
+ int result = a.compareTo(b);
+ return result <= 0 ? a : b;
+ }
+
+ /**
+ * Returns the larger of the two values, according to their natural ordering.
+ * If the values are equal, the first is returned.
+ *
+ * <p>To handle more than two values, call
+ * {@link Ordering#max(Object, Object, Object, Object...)} or
+ * {@link Ordering#max(Iterable)} on the {@link Ordering} returned by
+ * {@link Ordering#natural()}.
+ *
+ * @param a non-null value to compare, returned if greater than or equal to b.
+ * @param b non-null value to compare.
+ * @throws ClassCastException if the parameters are not mutually comparable
+ * (for example, a string and an integer).
+ */
+ @SuppressWarnings("unchecked") // see explanation in class Javadoc
+ public static <T extends Comparable> T max(T a, T b) {
+ /*
+ * Let this throw a ClassCastException if T is a bizarre Comparable that
+ * can't be compared to itself, as documented.
+ */
+ int result = a.compareTo(b);
+ return result >= 0 ? a : b;
+ }
+
+ /**
+ * Returns the smaller of the two values according to the specified
+ * comparator. If the values are equal, the first is returned. Null values
+ * are allowed if the comparator supports them.
+ *
+ * <p>To handle more than two values, call
+ * {@link Ordering#min(Object, Object, Object, Object...)} or
+ * {@link Ordering#min(Iterable)} on the {@link Ordering} returned by
+ * {@link Ordering#forComparator(Comparator)}.
+ *
+ * @param comparator comparator that compares the two values
+ * @param a value to compare, returned if less than or equal to b
+ * @param b value to compare
+ */
+ public static <T> T min(Comparator<? super T> comparator, @Nullable T a,
+ @Nullable T b) {
+ return comparator.compare(a, b) <= 0 ? a : b;
+ }
+
+ /**
+ * Returns the larger of the two values according to the specified comparator.
+ * If the values are equal, the first is returned. Null values are allowed if
+ * the comparator supports them.
+ *
+ * <p>To handle more than two values, call
+ * {@link Ordering#max(Object, Object, Object, Object...)} or
+ * {@link Ordering#max(Iterable)} on the {@link Ordering} returned by
+ * {@link Ordering#forComparator(Comparator)}.
+ *
+ * @param comparator comparator that compares the two values
+ * @param a value to compare, returned if greater than or equal to b
+ * @param b value to compare
+ */
+ public static <T> T max(Comparator<? super T> comparator, @Nullable T a,
+ @Nullable T b) {
+ return comparator.compare(a, b) >= 0 ? a : b;
+ }
+
+ /**
+ * Returns a comparator that compares objects according to the order in
+ * which they appear in the given list. Only objects present in the list
+ * (according to {@link Object#equals}) may be compared. This comparator
+ * imposes a "partial ordering" over the type {@code T}. Subsequent changes
+ * to the {@code valuesInOrder} list will have no effect on the returned
+ * comparator. Null values in the list are supported.
+ *
+ * <p>The returned comparator throws an {@link ClassCastException} when it
+ * receives an input parameter that isn't in {@code valuesInOrder}.
+ *
+ * @param valuesInOrder the values that the returned comparator will be able
+ * to compare, in the order the comparator should follow
+ * @return the comparator described above
+ * @throws IllegalArgumentException if {@code valuesInOrder} contains any
+ * non-consecutive duplicate values (according to {@link Object#equals})
+ */
+ public static <T> Ordering<T> givenOrder(List<? extends T> valuesInOrder) {
+ return new GivenOrder<T>(valuesInOrder);
+ }
+
+ /**
+ * Returns the comparator that compares objects according to the order in
+ * which they are given to this method. Only objects present in the argument
+ * list (according to {@link Object#equals}) may be compared. This comparator
+ * imposes a "partial ordering" over the type {@code T}. Null values in the
+ * argument list are supported.
+ *
+ * <p>The returned comparator throws a {@link ClassCastException} when it
+ * receives an input parameter that isn't equal to {@code leastValue}
+ * or in {@code remainingValuesInOrder}.
+ *
+ * @param leastValue the value which the returned comparator should consider
+ * the "least" of all values
+ * @param remainingValuesInOrder the rest of the values that the returned
+ * comparator will be able to compare, in the order the comparator should
+ * follow
+ * @return the comparator described above
+ * @throws IllegalArgumentException if any non-consecutive duplicate values
+ * (according to {@link Object#equals}) are present among the method
+ * arguments
+ */
+ public static <T> Ordering<T> givenOrder(
+ @Nullable T leastValue, T... remainingValuesInOrder) {
+ return givenOrder(Lists.asList(leastValue, remainingValuesInOrder));
+ }
+
+ /** @see Comparators#givenOrder(List) */
+ private static class GivenOrder<T> extends Ordering<T> {
+ final Map<T, Integer> rankMap;
+
+ GivenOrder(List<? extends T> valuesInOrder) {
+ rankMap = buildRankMap(valuesInOrder);
+ }
+
+ public int compare(T left, T right) {
+ return rank(left) - rank(right); // safe because both are nonnegative
+ }
+
+ int rank(T value) {
+ Integer rank = rankMap.get(value);
+ if (rank == null) {
+ throw new IncomparableValueException(value);
+ }
+ return rank;
+ }
+
+ static <T> Map<T, Integer> buildRankMap(
+ Collection<? extends T> valuesInOrder) {
+ Map<T, Integer> ranks
+ = Maps.newHashMapWithExpectedSize(valuesInOrder.size());
+ T previousValue = null;
+ int rank = 0;
+ for (T value : valuesInOrder) {
+ if ((rank == 0) || !Objects.equal(value, previousValue)) {
+ Integer priorRank = ranks.put(value, rank);
+ if (priorRank != null) {
+ throw new DuplicateValueException(value, priorRank, rank);
+ }
+ }
+ rank++;
+ previousValue = value;
+ }
+ return ranks;
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object instanceof GivenOrder) {
+ GivenOrder<?> that = (GivenOrder<?>) object;
+ return (this.rankMap).equals(that.rankMap);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return rankMap.hashCode();
+ }
+
+ @Override public String toString() {
+ return "givenOrder(" + rankMap + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Exception thrown by a {@link #givenOrder(List)} or
+ * {@link #givenOrder(Object, Object...)} comparator when comparing a value
+ * outside the set of values it can compare. Extending
+ * {@link ClassCastException} may seem odd, but it fits the spirit of the
+ * {@link Comparator#compare} specification, if you consider that we are
+ * handling what is conceptually a "subtype" of {@code T}.
+ */
+ static class IncomparableValueException extends ClassCastException {
+ final Object value;
+
+ IncomparableValueException(Object value) {
+ super("Cannot compare value: " + value);
+ this.value = value;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Exception thrown when a duplicate value is found in a list or array which
+ * is not expected to contain any.
+ */
+ static class DuplicateValueException extends IllegalArgumentException {
+ private static final long serialVersionUID = 0;
+ final Object value;
+ final int firstIndex;
+ final int secondIndex;
+
+ DuplicateValueException(Object value, int firstIndex, int secondIndex) {
+ super(String.format("Duplicate value at indices %s and %s: %s",
+ firstIndex, secondIndex, value));
+ this.value = value;
+ this.firstIndex = firstIndex;
+ this.secondIndex = secondIndex;
+ }
+ }
+
+ /**
+ * Compares the two specified {@code byte} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Byte.valueOf(a).compareTo(Byte.valueOf(b))</pre>
+ *
+ * @param a the first {@code byte} to compare
+ * @param b the second {@code byte} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ */
+ public static int compare(byte a, byte b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+ }
+
+ /**
+ * Compares the two specified {@code char} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Character.valueOf(a).compareTo(Character.valueOf(b))</pre>
+ *
+ * @param a the first {@code char} to compare
+ * @param b the second {@code char} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ */
+ public static int compare(char a, char b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+ }
+
+ /**
+ * Compares the two specified {@code short} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Short.valueOf(a).compareTo(Short.valueOf(b))</pre>
+ *
+ * @param a the first {@code short} to compare
+ * @param b the second {@code short} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ */
+ public static int compare(short a, short b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+ }
+
+ /**
+ * Compares the two specified {@code int} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Integer.valueOf(a).compareTo(Integer.valueOf(b))</pre>
+ *
+ * @param a the first {@code int} to compare
+ * @param b the second {@code int} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ */
+ public static int compare(int a, int b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+ }
+
+ /**
+ * Compares the two specified {@code long} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Long.valueOf(a).compareTo(Long.valueOf(b))</pre>
+ *
+ * @param a the first {@code long} to compare
+ * @param b the second {@code long} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ */
+ public static int compare(long a, long b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+ }
+
+ /**
+ * Compares the two specified {@code double} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Double.valueOf(a).compareTo(Double.valueOf(b))</pre>
+ *
+ * @param a the first {@code double} to compare
+ * @param b the second {@code double} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ * @see Double#compare
+ */
+ public static int compare(double a, double b) {
+ return Double.compare(a, b); // takes care of Double.NaN
+ }
+
+ /**
+ * Compares the two specified {@code float} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Float.valueOf(a).compareTo(Float.valueOf(b))</pre>
+ *
+ * @param a the first {@code float} to compare
+ * @param b the second {@code float} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; otherwise zero.
+ * @see Float#compare
+ */
+ public static int compare(float a, float b) {
+ return Float.compare(a, b); // takes care of Float.NaN
+ }
+
+ /**
+ * Compares the two specified {@code boolean} values. The sign of the value
+ * returned is the same as that of the value that would be returned by the
+ * call:
+ *
+ * <pre> Boolean.valueOf(a).compareTo(Boolean.valueOf(b))</pre>
+ *
+ * @param a the first {@code boolean} to compare
+ * @param b the second {@code boolean} to compare
+ * @return a negative value if {@code a} is false and {@code b} is true; a
+ * positive value if {@code a} is true and {@code b} is false; otherwise
+ * zero.
+ */
+ public static int compare(boolean a, boolean b) {
+ return (a == b) ? 0 : (a ? 1 : -1);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ConcurrentMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ConcurrentMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ConcurrentMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,455 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A multiset that supports concurrent modifications and that provides atomic
+ * versions of most {@code Multiset} operations (exceptions where noted). Null
+ * elements are not supported.
+ *
+ * @author Cliff L. Biffle
+ */
+public final class ConcurrentMultiset<E> extends AbstractMultiset<E>
+ implements Serializable {
+ /*
+ * The ConcurrentMultiset's atomic operations are implemented in terms of
+ * ConcurrentMap's atomic operations. Many of them, such as add(E, int), are
+ * read-modify-write sequences, and so are implemented as loops that wrap
+ * ConcurrentMap's compare-and-set operations (like putIfAbsent).
+ */
+
+ /** The number of occurrences of each element. */
+ private transient final ConcurrentMap<E, Integer> countMap;
+
+ /**
+ * Creates an empty instance.
+ */
+ public ConcurrentMultiset() {
+ this(new ConcurrentHashMap<E, Integer>());
+ }
+
+ /**
+ * Creates an instance that contains the elements in a given collection.
+ */
+ public ConcurrentMultiset(Collection<? extends E> collection) {
+ this(new ConcurrentHashMap<E, Integer>(Maps.capacity(collection.size())));
+ addAll(collection);
+ }
+
+ /**
+ * Creates an instance using {@code countMap} to store elements and their
+ * counts.
+ *
+ * <p>This instance will assume ownership of {@code countMap}, and other code
+ * should not maintain references to the map or modify it in any way.
+ *
+ * @param countMap backing map for storing the elements in the multiset and
+ * their counts. It must be empty.
+ * @throws IllegalArgumentException if {@code countMap} is not empty
+ */
+ ConcurrentMultiset(ConcurrentMap<E, Integer> countMap) {
+ checkArgument(countMap.isEmpty());
+ this.countMap = countMap;
+ }
+
+ // Query Operations
+
+ /**
+ * Returns the number of occurrences of {@code element} in this multiset.
+ *
+ * @param element the element to look for
+ * @return the nonnegative number of occurrences of the element
+ */
+ @Override public int count(@Nullable Object element) {
+ try {
+ return unbox(countMap.get(element));
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>If the data in the multiset is modified by any other threads during this
+ * method, it is undefined which (if any) of these modifications will be
+ * reflected in the result.
+ */
+ @Override public int size() {
+ long sum = 0L;
+ for (Integer value : countMap.values()) {
+ sum += value;
+ }
+ return (int) Math.min(sum, Integer.MAX_VALUE);
+ }
+
+ /*
+ * Note: the superclass toArray() methods assume that size() gives a correct
+ * answer, which ours does not.
+ */
+
+ @Override public Object[] toArray() {
+ return snapshot().toArray();
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return snapshot().toArray(array);
+ }
+
+ /*
+ * We'd love to use 'new ArrayList(this)' or 'list.addAll(this)', but
+ * either of these would recurse back to us again!
+ */
+ private List<E> snapshot() {
+ List<E> list = Lists.newArrayListWithExpectedSize(size());
+ for (Multiset.Entry<E> entry : entrySet()) {
+ E element = entry.getElement();
+ for (int i = entry.getCount(); i > 0; i--) {
+ list.add(element);
+ }
+ }
+ return list;
+ }
+
+ // Modification Operations
+
+ /**
+ * Adds a number of occurrences of the specified element to this multiset.
+ *
+ * @param element the element to add
+ * @param occurrences the number of occurrences to add
+ * @return {@code true} if the collection changed as a result (this should
+ * always be the case unless {@code occurrences} is zero)
+ * @throws IllegalArgumentException if {@code occurrences} is negative, or if
+ * the resulting amount would exceed {@link Integer#MAX_VALUE}
+ */
+ @Override public boolean add(E element, int occurrences) {
+ if (occurrences == 0) {
+ return false;
+ }
+ checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
+
+ while (true) {
+ int current = count(element);
+ if (current == 0) {
+ if (countMap.putIfAbsent(element, occurrences) == null) {
+ return true;
+ }
+ } else {
+ checkArgument(occurrences <= Integer.MAX_VALUE - current,
+ "Overflow adding %s occurrences to a count of %s",
+ occurrences, current);
+ int next = current + occurrences;
+ if (countMap.replace(element, current, next)) {
+ return true;
+ }
+ }
+ // If we're still here, there was a race, so just try again.
+ }
+ }
+
+ /**
+ * Removes a number of occurrences of the specified element from this
+ * multiset. If the multiset contains fewer than this number of occurrences to
+ * begin with, all occurrences will be removed.
+ *
+ * @param element the element whose occurrences should be removed
+ * @param occurrences the number of occurrences of this element to remove
+ * @return the number of occurrences that were successfully removed (zero if
+ * the element was not present)
+ * @throws IllegalArgumentException if {@code occurrences} is negative
+ */
+ @Override public int remove(@Nullable Object element, int occurrences) {
+ if (occurrences == 0) {
+ return 0;
+ }
+ checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
+
+ while (true) {
+ int current = count(element);
+ if (current == 0) {
+ return 0;
+ }
+ if (occurrences >= current) {
+ if (countMap.remove(element, current)) {
+ return current;
+ }
+ } else {
+ // We know it's an "E" because it already exists in the map.
+ @SuppressWarnings("unchecked")
+ E casted = (E) element;
+
+ if (countMap.replace(casted, current, current - occurrences)) {
+ return occurrences;
+ }
+ }
+ // If we're still here, there was a race, so just try again.
+ }
+ }
+
+ /**
+ * Removes <b>all</b> occurrences of the specified element from this multiset.
+ * This method complements {@link Multiset#remove(Object)}, which removes only
+ * one occurrence at a time.
+ *
+ * @param element the element whose occurrences should all be removed
+ * @return the number of occurrences successfully removed, possibly zero
+ */
+ @Override public int removeAllOccurrences(@Nullable Object element) {
+ try {
+ return unbox(countMap.remove(element));
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Removes exactly the specified number of occurrences of {@code element}, or
+ * makes no change if this is not possible.
+ *
+ * <p>This method, in contrast to {@link #remove(Object, int)}, has no effect
+ * when the element count is smaller than {@code occurrences}.
+ *
+ * @param element the element to remove
+ * @param occurrences the number of occurrences of {@code element} to remove
+ * @return {@code true} if the removal was possible (including if {@code
+ * occurrences} is zero)
+ */
+ public boolean removeExactly(@Nullable Object element, int occurrences) {
+ if (occurrences == 0) {
+ return true;
+ }
+ checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
+
+ while (true) {
+ int current = count(element);
+ if (occurrences > current) {
+ return false;
+ }
+ if (occurrences == current) {
+ if (countMap.remove(element, occurrences)) {
+ return true;
+ }
+ } else {
+ @SuppressWarnings("unchecked") // it's in the map, must be an "E"
+ E casted = (E) element;
+ if (countMap.replace(casted, current, current - occurrences)) {
+ return true;
+ }
+ }
+ // If we're still here, there was a race, so just try again.
+ }
+ }
+ /**
+ * Adds or removes occurrences of {@code element} such that the {@link #count}
+ * of the element becomes {@code count}.
+ *
+ * @return the count of {@code element} in the multiset before this call
+ * @throws IllegalArgumentException if {@code count} is negative
+ */
+ public int setCount(E element, int count) {
+ checkArgument(count >= 0, "Invalid count: %s", count);
+ return (count == 0)
+ ? removeAllOccurrences(element)
+ : unbox(countMap.put(element, count));
+ }
+
+ /**
+ * Sets the number of occurrences of {@code element} to {@code newCount}, but
+ * only if the count is currently {@code oldCount}. If {@code element} does
+ * not appear in the multiset exactly {@code oldCount} times, no changes will
+ * be made.
+ *
+ * @return {@code true} if the change was successful. This usually indicates
+ * that the multiset has been modified, but not always: in the case that
+ * {@code oldCount == newCount}, the method will return {@code true} if
+ * the condition was met.
+ * @throws IllegalArgumentException if {@code oldCount} or {@code newCount} is
+ * negative
+ */
+ public boolean setCount(E element, int oldCount, int newCount) {
+ checkArgument(oldCount >= 0, "Invalid oldCount: %s", oldCount);
+ checkArgument(newCount >= 0, "Invalid newCount: %s", newCount);
+ if (newCount == 0) {
+ if (oldCount == 0) {
+ // No change to make, but must return true if the element is not present
+ return !countMap.containsKey(element);
+ } else {
+ return countMap.remove(element, oldCount);
+ }
+ }
+ if (oldCount == 0) {
+ return countMap.putIfAbsent(element, newCount) == null;
+ }
+ return countMap.replace(element, oldCount, newCount);
+ }
+
+ // Views
+
+ @Override public Set<E> elementSet() {
+ return countMap.keySet();
+ }
+
+ private volatile transient EntrySet entrySet;
+
+ @Override public Set<Multiset.Entry<E>> entrySet() {
+ EntrySet result = entrySet;
+ if (result == null) {
+ entrySet = result = new EntrySet();
+ }
+ return result;
+ }
+
+ private class EntrySet extends AbstractSet<Multiset.Entry<E>> {
+ @Override public int size() {
+ return countMap.size();
+ }
+
+ @Override public boolean isEmpty() {
+ return countMap.isEmpty();
+ }
+
+ @Override public boolean contains(Object object) {
+ if (object instanceof Multiset.Entry) {
+ Multiset.Entry<?> entry = (Multiset.Entry<?>) object;
+ Object element = entry.getElement();
+ int entryCount = entry.getCount();
+ return entryCount > 0 && count(element) == entryCount;
+ }
+ return false;
+ }
+
+ @Override public Iterator<Multiset.Entry<E>> iterator() {
+ final Iterator<Map.Entry<E, Integer>> backingIterator
+ = countMap.entrySet().iterator();
+ return new Iterator<Multiset.Entry<E>>() {
+ public boolean hasNext() {
+ return backingIterator.hasNext();
+ }
+
+ public Multiset.Entry<E> next() {
+ Map.Entry<E, Integer> backingEntry = backingIterator.next();
+ return Multisets.immutableEntry(
+ backingEntry.getKey(), backingEntry.getValue());
+ }
+
+ public void remove() {
+ backingIterator.remove();
+ }
+ };
+ }
+
+ /*
+ * Note: the superclass toArray() methods assume that size() gives a correct
+ * answer, which ours does not.
+ */
+
+ @Override public Object[] toArray() {
+ return snapshot().toArray();
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return snapshot().toArray(array);
+ }
+
+ /*
+ * We'd love to use 'new ArrayList(this)' or 'list.addAll(this)', but
+ * either of these would recurse back to us again!
+ */
+ private List<Multiset.Entry<E>> snapshot() {
+ List<Multiset.Entry<E>> list = Lists.newArrayListWithExpectedSize(size());
+ for (Multiset.Entry<E> entry : this) {
+ list.add(entry);
+ }
+ return list;
+ }
+
+ @Override public boolean remove(Object object) {
+ if (object instanceof Multiset.Entry) {
+ Multiset.Entry<?> entry = (Multiset.Entry<?>) object;
+ Object element = entry.getElement();
+ int entryCount = entry.getCount();
+ return countMap.remove(element, entryCount);
+ }
+ return false;
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+
+ @Override public void clear() {
+ countMap.clear();
+ }
+
+ /**
+ * The hash code is the same as countMap's, though the objects aren't equal.
+ */
+ @Override public int hashCode() {
+ return countMap.hashCode();
+ }
+ }
+
+ /**
+ * We use a special form of unboxing that treats null as zero.
+ */
+ private static int unbox(Integer i) {
+ return (i == null) ? 0 : i;
+ }
+
+ /**
+ * @serialData the number of distinct elements, the first element, its count,
+ * the second element, its count, and so on
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ // creating HashMultiset to handle concurrent changes
+ Serialization.writeMultiset(HashMultiset.create(this), stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException, NoSuchFieldException {
+ stream.defaultReadObject();
+ Serialization.setFinalField(ConcurrentMultiset.class, this, "countMap",
+ Maps.newConcurrentHashMap());
+ Serialization.populateMultiset(this, stream);
+ }
+
+ private static final long serialVersionUID = 0L;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraint.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraint.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraint.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+/**
+ * A constraint that an element must satisfy in order to be added to a
+ * collection. For example, {@link Constraints#notNull()}, which prevents a
+ * collection from including any null elements, could be implemented like this:
+ * <pre> {@code
+ *
+ * public Object checkElement(Object element) {
+ * if (element == null) {
+ * throw new NullPointerException();
+ * }
+ * return element;
+ * }}</pre>
+ *
+ * In order to be effective, constraints should be deterministic; that is,
+ * they should not depend on state that can change (such as external state,
+ * random variables, and time) and should only depend on the value of the
+ * passed-in element. A non-deterministic constraint cannot reliably enforce
+ * that all the collection's elements meet the constraint, since the constraint
+ * is only enforced when elements are added.
+ *
+ * @see Constraints
+ * @see MapConstraint
+ * @author Mike Bostock
+ */
+public interface Constraint<E> {
+ /**
+ * Throws a suitable {@code RuntimeException} if the specified element is
+ * illegal. Typically this is either a {@link NullPointerException}, an
+ * {@link IllegalArgumentException}, or a {@link ClassCastException}, though
+ * an application-specific exception class may be used if appropriate.
+ *
+ * @param element the element to check
+ * @return the provided element
+ */
+ E checkElement(E element);
+
+ /**
+ * Returns a brief human readable description of this constraint, such as
+ * "Not null" or "Positive number".
+ */
+ String toString();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraints.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraints.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Constraints.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * Factories and utilities pertaining to the {@link Constraint} interface.
+ *
+ * @see MapConstraints
+ * @author Mike Bostock
+ * @author Jared Levy
+ */
+public final class Constraints {
+ private Constraints() {}
+
+ // enum singleton pattern
+ private enum NotNullConstraint implements Constraint<Object> {
+ INSTANCE;
+
+ public Object checkElement(Object element) {
+ return checkNotNull(element);
+ }
+
+ @Override public String toString() {
+ return "Not null";
+ }
+ }
+
+ /**
+ * Returns a constraint that verifies that the element is not null. If the
+ * element is null, a {@link NullPointerException} is thrown.
+ */
+ @SuppressWarnings("unchecked") // the cast is safe
+ public static final <E> Constraint<E> notNull() {
+ return (Constraint<E>) NotNullConstraint.INSTANCE;
+ }
+
+ /**
+ * Returns a constrained view of the specified collection, using the specified
+ * constraint. Any operations that add new elements to the collection will
+ * call the provided constraint. However, this method does not verify that
+ * existing elements satisfy the constraint.
+ *
+ * <p>The returned collection is not serializable.
+ *
+ * @param collection the collection to constrain
+ * @param constraint the constraint that validates added elements
+ * @return a constrained view of the collection
+ */
+ public static <E> Collection<E> constrainedCollection(
+ Collection<E> collection, Constraint<? super E> constraint) {
+ return new ConstrainedCollection<E>(collection, constraint);
+ }
+
+ /** @see Constraints#constrainedCollection */
+ static class ConstrainedCollection<E> extends ForwardingCollection<E> {
+ private final Collection<E> delegate;
+ private final Constraint<? super E> constraint;
+
+ public ConstrainedCollection(
+ Collection<E> delegate, Constraint<? super E> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+ @Override protected Collection<E> delegate() {
+ return delegate;
+ }
+ @Override public boolean add(E element) {
+ constraint.checkElement(element);
+ return delegate.add(element);
+ }
+ @Override public boolean addAll(Collection<? extends E> elements) {
+ return delegate.addAll(checkElements(elements, constraint));
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified set, using the specified
+ * constraint. Any operations that add new elements to the set will call the
+ * provided constraint. However, this method does not verify that existing
+ * elements satisfy the constraint.
+ *
+ * <p>The returned set is not serializable.
+ *
+ * @param set the set to constrain
+ * @param constraint the constraint that validates added elements
+ * @return a constrained view of the set
+ */
+ public static <E> Set<E> constrainedSet(
+ Set<E> set, Constraint<? super E> constraint) {
+ return new ConstrainedSet<E>(set, constraint);
+ }
+
+ /** @see Constraints#constrainedSet */
+ static class ConstrainedSet<E> extends ForwardingSet<E> {
+ private final Set<E> delegate;
+ private final Constraint<? super E> constraint;
+
+ public ConstrainedSet(Set<E> delegate, Constraint<? super E> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+ @Override public boolean add(E element) {
+ constraint.checkElement(element);
+ return delegate.add(element);
+ }
+ @Override public boolean addAll(Collection<? extends E> elements) {
+ return delegate.addAll(checkElements(elements, constraint));
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified sorted set, using the specified
+ * constraint. Any operations that add new elements to the sorted set will
+ * call the provided constraint. However, this method does not verify that
+ * existing elements satisfy the constraint.
+ *
+ * <p>The returned set is not serializable.
+ *
+ * @param sortedSet the sorted set to constrain
+ * @param constraint the constraint that validates added elements
+ * @return a constrained view of the sorted set
+ */
+ public static <E> SortedSet<E> constrainedSortedSet(
+ SortedSet<E> sortedSet, Constraint<? super E> constraint) {
+ return new ConstrainedSortedSet<E>(sortedSet, constraint);
+ }
+
+ /** @see Constraints#constrainedSortedSet */
+ private static class ConstrainedSortedSet<E> extends ForwardingSortedSet<E> {
+ final SortedSet<E> delegate;
+ final Constraint<? super E> constraint;
+
+ ConstrainedSortedSet(
+ SortedSet<E> delegate, Constraint<? super E> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+ @Override protected SortedSet<E> delegate() {
+ return delegate;
+ }
+ @Override public SortedSet<E> headSet(E toElement) {
+ return constrainedSortedSet(delegate.headSet(toElement), constraint);
+ }
+ @Override public SortedSet<E> subSet(E fromElement, E toElement) {
+ return constrainedSortedSet(
+ delegate.subSet(fromElement, toElement), constraint);
+ }
+ @Override public SortedSet<E> tailSet(E fromElement) {
+ return constrainedSortedSet(delegate.tailSet(fromElement), constraint);
+ }
+ @Override public boolean add(E element) {
+ constraint.checkElement(element);
+ return delegate.add(element);
+ }
+ @Override public boolean addAll(Collection<? extends E> elements) {
+ return delegate.addAll(checkElements(elements, constraint));
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified list, using the specified
+ * constraint. Any operations that add new elements to the list will call the
+ * provided constraint. However, this method does not verify that existing
+ * elements satisfy the constraint.
+ *
+ * <p>If {@code list} implements {@link RandomAccess}, so will the returned
+ * list. The returned list is not serializable.
+ *
+ * @param list the list to constrain
+ * @param constraint the constraint that validates added elements
+ * @return a constrained view of the list
+ */
+ public static <E> List<E> constrainedList(
+ List<E> list, Constraint<? super E> constraint) {
+ return (list instanceof RandomAccess)
+ ? new ConstrainedRandomAccessList<E>(list, constraint)
+ : new ConstrainedList<E>(list, constraint);
+ }
+
+ /** @see Constraints#constrainedList */
+ private static class ConstrainedList<E> extends ForwardingList<E> {
+ final List<E> delegate;
+ final Constraint<? super E> constraint;
+
+ ConstrainedList(List<E> delegate, Constraint<? super E> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+ @Override protected List<E> delegate() {
+ return delegate;
+ }
+
+ @Override public boolean add(E element) {
+ constraint.checkElement(element);
+ return delegate.add(element);
+ }
+ @Override public void add(int index, E element) {
+ constraint.checkElement(element);
+ delegate.add(index, element);
+ }
+ @Override public boolean addAll(Collection<? extends E> elements) {
+ return delegate.addAll(checkElements(elements, constraint));
+ }
+ @Override public boolean addAll(int index, Collection<? extends E> elements)
+ {
+ return delegate.addAll(index, checkElements(elements, constraint));
+ }
+ @Override public ListIterator<E> listIterator() {
+ return constrainedListIterator(delegate.listIterator(), constraint);
+ }
+ @Override public ListIterator<E> listIterator(int index) {
+ return constrainedListIterator(delegate.listIterator(index), constraint);
+ }
+ @Override public E set(int index, E element) {
+ constraint.checkElement(element);
+ return delegate.set(index, element);
+ }
+ @Override public List<E> subList(int fromIndex, int toIndex) {
+ return constrainedList(delegate.subList(fromIndex, toIndex), constraint);
+ }
+ }
+
+ /** @see Constraints#constrainedList */
+ static class ConstrainedRandomAccessList<E> extends ConstrainedList<E>
+ implements RandomAccess {
+ ConstrainedRandomAccessList(
+ List<E> delegate, Constraint<? super E> constraint) {
+ super(delegate, constraint);
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified list iterator, using the
+ * specified constraint. Any operations that would add new elements to the
+ * underlying list will be verified by the constraint.
+ *
+ * @param listIterator the iterator for which to return a constrained view
+ * @param constraint the constraint for elements in the list
+ * @return a constrained view of the specified iterator
+ */
+ // TODO: Make public?
+ private static <E> ListIterator<E> constrainedListIterator(
+ ListIterator<E> listIterator, Constraint<? super E> constraint) {
+ return new ConstrainedListIterator<E>(listIterator, constraint);
+ }
+
+ /** @see Constraints#constrainedListIterator */
+ static class ConstrainedListIterator<E> extends ForwardingListIterator<E> {
+ private final ListIterator<E> delegate;
+ private final Constraint<? super E> constraint;
+
+ public ConstrainedListIterator(
+ ListIterator<E> delegate, Constraint<? super E> constraint) {
+ this.delegate = delegate;
+ this.constraint = constraint;
+ }
+ @Override protected ListIterator<E> delegate() {
+ return delegate;
+ }
+
+ @Override public void add(E element) {
+ constraint.checkElement(element);
+ delegate.add(element);
+ }
+ @Override public void set(E element) {
+ constraint.checkElement(element);
+ delegate.set(element);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ static <E> Collection<E> constrainedTypePreservingCollection(
+ Collection<E> collection, Constraint<E> constraint) {
+ if (collection instanceof SortedSet) {
+ return constrainedSortedSet((SortedSet<E>) collection, constraint);
+ } else if (collection instanceof Set) {
+ return constrainedSet((Set<E>) collection, constraint);
+ } else if (collection instanceof List) {
+ return constrainedList((List<E>) collection, constraint);
+ } else {
+ return constrainedCollection(collection, constraint);
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified multiset, using the specified
+ * constraint. Any operations that add new elements to the multiset will call
+ * the provided constraint. However, this method does not verify that
+ * existing elements satisfy the constraint.
+ *
+ * <p>The returned multiset is not serializable.
+ *
+ * @param multiset the multiset to constrain
+ * @param constraint the constraint that validates added elements
+ * @return a constrained view of the multiset
+ */
+ public static <E> Multiset<E> constrainedMultiset(
+ Multiset<E> multiset, Constraint<? super E> constraint) {
+ return new ConstrainedMultiset<E>(multiset, constraint);
+ }
+
+ /** @see Constraints#constrainedMultiset */
+ static class ConstrainedMultiset<E> extends ForwardingMultiset<E> {
+ private Multiset<E> delegate;
+ private final Constraint<? super E> constraint;
+
+ public ConstrainedMultiset(
+ Multiset<E> delegate, Constraint<? super E> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+ @Override protected Multiset<E> delegate() {
+ return delegate;
+ }
+
+ @Override public boolean add(E element) {
+ constraint.checkElement(element);
+ return delegate.add(element);
+ }
+ @Override public boolean addAll(Collection<? extends E> elements) {
+ return delegate.addAll(checkElements(elements, constraint));
+ }
+ @Override public boolean add(E element, int occurrences) {
+ constraint.checkElement(element);
+ return delegate.add(element, occurrences);
+ }
+ }
+
+ // TODO: For better performance, avoid making a copy of the elements by having
+ // addAll() call add() repeatedly instead.
+
+ private static <E> Collection<E> checkElements(
+ Collection<E> elements, Constraint<? super E> constraint) {
+ Collection<E> copy = Lists.newArrayList(elements);
+ for (E element : copy) {
+ constraint.checkElement(element);
+ }
+ return copy;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumBiMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumBiMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumBiMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.EnumMap;
+import java.util.Map;
+
+/**
+ * A {@code BiMap} backed by two {@code EnumMap} instances. Null keys and values
+ * are not permitted. An {@code EnumBiMap} and its inverse are both
+ * serializable.
+ *
+ * @author Mike Bostock
+ */
+public final class EnumBiMap<K extends Enum<K>, V extends Enum<V>>
+ extends StandardBiMap<K, V> {
+ private transient Class<K> keyType;
+ private transient Class<V> valueType;
+
+ /**
+ * Constructs a new empty bimap using the specified key type and value type.
+ *
+ * @param keyType the key type
+ * @param valueType the value type
+ */
+ public EnumBiMap(Class<K> keyType, Class<V> valueType) {
+ super(new EnumMap<K, V>(keyType), new EnumMap<V, K>(valueType));
+ this.keyType = keyType;
+ this.valueType = valueType;
+ }
+
+ /**
+ * Constructs a new bimap with the same mappings as the specified map. If the
+ * specified map is an {@code EnumBiMap}, the new bimap has the same types as
+ * the provided map. Otherwise, the specified map must contain at least one
+ * mapping, in order to determine the key and value types.
+ *
+ * @param map the map whose mappings are to be placed in this map
+ * @throws IllegalArgumentException if map is not an {@code EnumBiMap}
+ * instance and contains no mappings
+ */
+ public EnumBiMap(Map<K, V> map) {
+ this(inferKeyType(map), inferValueType(map));
+ putAll(map); // careful if we make this class non-final
+ }
+
+ static <K extends Enum<K>> Class<K> inferKeyType(Map<K, ?> map) {
+ if (map instanceof EnumBiMap) {
+ return ((EnumBiMap<K, ?>) map).keyType();
+ }
+ if (map instanceof EnumHashBiMap) {
+ return ((EnumHashBiMap<K, ?>) map).keyType();
+ }
+ checkArgument(!map.isEmpty());
+ return map.keySet().iterator().next().getDeclaringClass();
+ }
+
+ private static <V extends Enum<V>> Class<V> inferValueType(Map<?, V> map) {
+ if (map instanceof EnumBiMap) {
+ return ((EnumBiMap<?, V>) map).valueType;
+ }
+ checkArgument(!map.isEmpty());
+ return map.values().iterator().next().getDeclaringClass();
+ }
+
+ /** Returns the associated key type. */
+ public Class<K> keyType() {
+ return keyType;
+ }
+
+ /** Returns the associated value type. */
+ public Class<V> valueType() {
+ return valueType;
+ }
+
+ /**
+ * @serialData the key class, value class, number of entries, first key, first
+ * value, second key, second value, and so on.
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(keyType);
+ stream.writeObject(valueType);
+ Serialization.writeMap(this, stream);
+ }
+
+ @SuppressWarnings("unchecked") // reading fields populated by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ keyType = (Class<K>) stream.readObject();
+ valueType = (Class<V>) stream.readObject();
+ setDelegates(new EnumMap<K, V>(keyType), new EnumMap<V, K>(valueType));
+ Serialization.populateMap(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumHashBiMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumHashBiMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumHashBiMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@code BiMap} backed by an {@code EnumMap} instance for keys-to-values, and
+ * a {@code HashMap} instance for values-to-keys. Null keys are not permitted,
+ * but null values are. An {@code EnumHashBiMap} and its inverse are both
+ * serializable.
+ *
+ * @author Mike Bostock
+ */
+public final class EnumHashBiMap<K extends Enum<K>, V>
+ extends StandardBiMap<K, V> {
+ private transient Class<K> keyType;
+
+ /**
+ * Constructs a new empty bimap using the specified key type, sized to contain
+ * an entry for every possible key.
+ *
+ * @param keyType the key type
+ */
+ public EnumHashBiMap(Class<K> keyType) {
+ super(new EnumMap<K, V>(keyType),
+ new HashMap<V, K>(keyType.getEnumConstants().length * 3 / 2));
+ this.keyType = keyType;
+ }
+
+ /**
+ * Constructs a new bimap with the same mappings as the specified map. If the
+ * specified map is an {@code EnumHashBiMap} or an {@link EnumBiMap}, the new
+ * bimap has the same key type as the input bimap. Otherwise, the specified
+ * map must contain at least one mapping, in order to determine the key type.
+ *
+ * @param map the map whose mappings are to be placed in this map
+ * @throws IllegalArgumentException if map is not an {@code EnumBiMap} or an
+ * {@code EnumHashBiMap} instance and contains no mappings
+ */
+ public EnumHashBiMap(Map<K, ? extends V> map) {
+ this(EnumBiMap.inferKeyType(map));
+ putAll(map); // careful if we make this class non-final
+ }
+
+ // Overriding these two methods to show that values may be null (but not keys)
+
+ @Override public V put(K key, @Nullable V value) {
+ return super.put(key, value);
+ }
+
+ @Override public V forcePut(K key, @Nullable V value) {
+ return super.forcePut(key, value);
+ }
+
+ /** Returns the associated key type. */
+ public Class<K> keyType() {
+ return keyType;
+ }
+
+ /**
+ * @serialData the key class, number of entries, first key, first value,
+ * second key, second value, and so on.
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(keyType);
+ Serialization.writeMap(this, stream);
+ }
+
+ @SuppressWarnings("unchecked") // reading field populated by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ keyType = (Class<K>) stream.readObject();
+ setDelegates(new EnumMap<K, V>(keyType),
+ new HashMap<V, K>(keyType.getEnumConstants().length * 3 / 2));
+ Serialization.populateMap(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/EnumMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.EnumMap;
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Multiset implementation backed by an {@link EnumMap}.
+ *
+ * @author Jared Levy
+ */
+public final class EnumMultiset<E extends Enum<E>>
+ extends AbstractMapBasedMultiset<E> {
+ private transient Class<E> type;
+
+ /** Creates an empty {@code EnumMultiset}. */
+ public EnumMultiset(Class<E> type) {
+ super(new EnumMap<E, AtomicInteger>(type));
+ this.type = type;
+ }
+
+ /**
+ * Creates a new {@code EnumMultiset} containing the specified elements.
+ *
+ * @param elements the elements that the multiset should contain
+ * @throws IllegalArgumentException if {@code elements} is empty
+ */
+ public EnumMultiset(Iterable<E> elements) {
+ this(findClass(elements));
+ Iterables.addAll(this, elements);
+ }
+
+ /**
+ * Determine the class of the first element in an {@link Iterable}.
+ *
+ * @param elements the elements to examine
+ * @return the {@link Class} of the first element
+ * @throws IllegalArgumentException if {@code elements} is empty
+ */
+ private static <E extends Enum<E>> Class<E> findClass(Iterable<E> elements) {
+ Iterator<E> iterator = elements.iterator();
+ checkArgument(iterator.hasNext(),
+ "EnumMultiset constructor passed empty Iterable");
+ return iterator.next().getDeclaringClass();
+ }
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(type);
+ Serialization.writeMultiset(this, stream);
+ }
+
+ /**
+ * @serialData the {@code Class<E>} for the enum type, the number of distinct
+ * elements, the first element, its count, the second element, its count,
+ * and so on
+ */
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ Class<E> localType = (Class<E>) stream.readObject();
+ type = localType;
+ setBackingMap(new EnumMap<E, AtomicInteger>(type));
+ Serialization.populateMultiset(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingCollection.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingCollection.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingCollection.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * A collection which forwards all its method calls to another collection.
+ * Subclasses should override one or more methods to modify the behavior of
+ * the backing collection as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Kevin Bourrillion
+ */
+public abstract class ForwardingCollection<E> extends ForwardingObject
+ implements Collection<E> {
+
+ @Override protected abstract Collection<E> delegate();
+
+ public Iterator<E> iterator() {
+ return delegate().iterator();
+ }
+
+ public int size() {
+ return delegate().size();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method always throws a {@link NullPointerException} when
+ * {@code collection} is null.
+ */
+ public boolean removeAll(Collection<?> collection) {
+ return delegate().removeAll(checkNotNull(collection));
+ }
+
+ public boolean isEmpty() {
+ return delegate().isEmpty();
+ }
+
+ public boolean contains(Object object) {
+ return delegate().contains(object);
+ }
+
+ public Object[] toArray() {
+ return delegate().toArray();
+ }
+
+ public <T> T[] toArray(T[] array) {
+ return delegate().toArray(array);
+ }
+
+ public boolean add(E element) {
+ return delegate().add(element);
+ }
+
+ public boolean remove(Object object) {
+ return delegate().remove(object);
+ }
+
+ public boolean containsAll(Collection<?> collection) {
+ return delegate().containsAll(collection);
+ }
+
+ public boolean addAll(Collection<? extends E> collection) {
+ return delegate().addAll(collection);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method always throws a {@link NullPointerException} when
+ * {@code collection} is null.
+ */
+ public boolean retainAll(Collection<?> collection) {
+ return delegate().retainAll(checkNotNull(collection));
+ }
+
+ public void clear() {
+ delegate().clear();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingConcurrentMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingConcurrentMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingConcurrentMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A concurrent map which forwards all its method calls to another concurrent
+ * map. Subclasses should override one or more methods to modify the behavior of
+ * the backing map as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Charles Fry
+ */
+public abstract class ForwardingConcurrentMap<K, V> extends ForwardingMap<K, V>
+ implements ConcurrentMap<K, V> {
+
+ @Override protected abstract ConcurrentMap<K, V> delegate();
+
+ public V putIfAbsent(K key, V value) {
+ return delegate().putIfAbsent(key, value);
+ }
+
+ public boolean remove(Object key, Object value) {
+ return delegate().remove(key, value);
+ }
+
+ public V replace(K key, V value) {
+ return delegate().replace(key, value);
+ }
+
+ public boolean replace(K key, V oldValue, V newValue) {
+ return delegate().replace(key, oldValue, newValue);
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingIterator.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingIterator.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingIterator.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Iterator;
+
+/**
+ * An iterator which forwards all its method calls to another iterator.
+ * Subclasses should override one or more methods to modify the behavior of the
+ * backing iterator as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Kevin Bourrillion
+ */
+public abstract class ForwardingIterator<T>
+ extends ForwardingObject implements Iterator<T> {
+
+ @Override protected abstract Iterator<T> delegate();
+
+ public boolean hasNext() {
+ return delegate().hasNext();
+ }
+
+ public T next() {
+ return delegate().next();
+ }
+
+ public void remove() {
+ delegate().remove();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingList.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingList.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingList.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * A list which forwards all its method calls to another list. Subclasses should
+ * override one or more methods to modify the behavior of the backing list as
+ * desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * <p>This class does not implement {@link java.util.RandomAccess}. If the
+ * delegate supports random access, the {@code ForwadingList} subclass should
+ * implement the {@code RandomAccess} interface.
+ *
+ * @author Mike Bostock
+ */
+public abstract class ForwardingList<E> extends ForwardingCollection<E>
+ implements List<E> {
+
+ @Override protected abstract List<E> delegate();
+
+ public void add(int index, E element) {
+ delegate().add(index, element);
+ }
+
+ public boolean addAll(int index, Collection<? extends E> elements) {
+ return delegate().addAll(index, elements);
+ }
+
+ public E get(int index) {
+ return delegate().get(index);
+ }
+
+ public int indexOf(Object element) {
+ return delegate().indexOf(element);
+ }
+
+ public int lastIndexOf(Object element) {
+ return delegate().lastIndexOf(element);
+ }
+
+ public ListIterator<E> listIterator() {
+ return delegate().listIterator();
+ }
+
+ public ListIterator<E> listIterator(int index) {
+ return delegate().listIterator(index);
+ }
+
+ public E remove(int index) {
+ return delegate().remove(index);
+ }
+
+ public E set(int index, E element) {
+ return delegate().set(index, element);
+ }
+
+ public List<E> subList(int fromIndex, int toIndex) {
+ return delegate().subList(fromIndex, toIndex);
+ }
+
+ @Override public boolean equals(Object obj) {
+ return (this == obj) || delegate().equals(obj);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingListIterator.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingListIterator.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingListIterator.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.ListIterator;
+
+/**
+ * A list iterator which forwards all its method calls to another list
+ * iterator. Subclasses should override one or more methods to modify the
+ * behavior of the backing iterator as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Mike Bostock
+ */
+public abstract class ForwardingListIterator<E> extends ForwardingIterator<E>
+ implements ListIterator<E> {
+
+ @Override protected abstract ListIterator<E> delegate();
+
+ public void add(E element) {
+ delegate().add(element);
+ }
+
+ public boolean hasPrevious() {
+ return delegate().hasPrevious();
+ }
+
+ public int nextIndex() {
+ return delegate().nextIndex();
+ }
+
+ public E previous() {
+ return delegate().previous();
+ }
+
+ public int previousIndex() {
+ return delegate().previousIndex();
+ }
+
+ public void set(E element) {
+ delegate().set(element);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A map which forwards all its method calls to another map. Subclasses should
+ * override one or more methods to modify the behavior of the backing map as
+ * desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Kevin Bourrillion
+ * @author Jared Levy
+ */
+public abstract class ForwardingMap<K, V> extends ForwardingObject
+ implements Map<K, V> {
+
+ @Override protected abstract Map<K, V> delegate();
+
+ public int size() {
+ return delegate().size();
+ }
+
+ public boolean isEmpty() {
+ return delegate().isEmpty();
+ }
+
+ public V remove(Object object) {
+ return delegate().remove(object);
+ }
+
+ public void clear() {
+ delegate().clear();
+ }
+
+ public boolean containsKey(Object key) {
+ return delegate().containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return delegate().containsValue(value);
+ }
+
+ public V get(Object key) {
+ return delegate().get(key);
+ }
+
+ public V put(K key, V value) {
+ return delegate().put(key, value);
+ }
+
+ public void putAll(Map<? extends K, ? extends V> map) {
+ delegate().putAll(map);
+ }
+
+ private transient Set<K> keySet;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned set's {@code removeAll} and {@code retainAll} methods
+ * always throw a {@link NullPointerException} when given a null collection.
+ */
+ public Set<K> keySet() {
+ return (keySet == null) ? keySet = createKeySet() : keySet;
+ }
+
+ private Set<K> createKeySet() {
+ final Set<K> delegate = delegate().keySet();
+ return new ForwardingSet<K>() {
+ @Override protected Set<K> delegate() {
+ return delegate;
+ }
+ };
+ }
+
+ private transient Collection<V> values;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned collection's {@code removeAll} and {@code retainAll}
+ * methods always throw a {@link NullPointerException} when given a null
+ * collection.
+ */
+ public Collection<V> values() {
+ return (values == null) ? values = createValues() : values;
+ }
+
+ private Collection<V> createValues() {
+ final Collection<V> delegate = delegate().values();
+ return new ForwardingCollection<V>() {
+ @Override protected Collection<V> delegate() {
+ return delegate;
+ }
+ };
+ }
+
+ private transient Set<Entry<K, V>> entrySet;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned set's {@code removeAll} and {@code retainAll} methods
+ * always throw a {@link NullPointerException} when given a null collection.
+ */
+ public Set<Entry<K, V>> entrySet() {
+ return (entrySet == null) ? entrySet = createEntrySet() : entrySet;
+ }
+
+ private Set<Entry<K, V>> createEntrySet() {
+ final Set<Entry<K, V>> delegate = delegate().entrySet();
+ return new ForwardingSet<Entry<K, V>>() {
+ @Override protected Set<Entry<K, V>> delegate() {
+ return delegate;
+ }
+ };
+ }
+
+ @Override public boolean equals(Object obj) {
+ return (this == obj) || delegate().equals(obj);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMapEntry.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMapEntry.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMapEntry.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Map;
+
+/**
+ * A map entry which forwards all its method calls to another map entry.
+ * Subclasses should override one or more methods to modify the behavior of the
+ * backing map entry as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Mike Bostock
+ */
+public abstract class ForwardingMapEntry<K, V>
+ extends ForwardingObject implements Map.Entry<K, V> {
+
+ @Override protected abstract Map.Entry<K, V> delegate();
+
+ public K getKey() {
+ return delegate().getKey();
+ }
+
+ public V getValue() {
+ return delegate().getValue();
+ }
+
+ public V setValue(V value) {
+ return delegate().setValue(value);
+ }
+
+ @Override public boolean equals(Object obj) {
+ return delegate().equals(obj);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * A multimap which forwards all its method calls to another multimap.
+ * Subclasses should override one or more methods to modify the behavior of
+ * the backing multimap as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Robert Konigsberg
+ */
+public abstract class ForwardingMultimap<K, V> extends ForwardingObject
+ implements Multimap<K, V> {
+
+ @Override protected abstract Multimap<K, V> delegate();
+
+ public Map<K, Collection<V>> asMap() {
+ return delegate().asMap();
+ }
+
+ public void clear() {
+ delegate().clear();
+ }
+
+ public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
+ return delegate().containsEntry(key, value);
+ }
+
+ public boolean containsKey(@Nullable Object key) {
+ return delegate().containsKey(key);
+ }
+
+ public boolean containsValue(@Nullable Object value) {
+ return delegate().containsValue(value);
+ }
+
+ public Collection<Entry<K, V>> entries() {
+ return delegate().entries();
+ }
+
+ public Collection<V> get(@Nullable K key) {
+ return delegate().get(key);
+ }
+
+ public boolean isEmpty() {
+ return delegate().isEmpty();
+ }
+
+ public Multiset<K> keys() {
+ return delegate().keys();
+ }
+
+ public Set<K> keySet() {
+ return delegate().keySet();
+ }
+
+ public boolean put(K key, V value) {
+ return delegate().put(key, value);
+ }
+
+ public boolean putAll(K key, Iterable<? extends V> values) {
+ return delegate().putAll(key, values);
+ }
+
+ public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ return delegate().putAll(multimap);
+ }
+
+ public boolean remove(@Nullable Object key, @Nullable Object value) {
+ return delegate().remove(key, value);
+ }
+
+ public Collection<V> removeAll(@Nullable Object key) {
+ return delegate().removeAll(key);
+ }
+
+ public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
+ return delegate().replaceValues(key, values);
+ }
+
+ public int size() {
+ return delegate().size();
+ }
+
+ public Collection<V> values() {
+ return delegate().values();
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ return (this == obj) || delegate().equals(obj);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Set;
+
+/**
+ * A multiset which forwards all its method calls to another multiset.
+ * Subclasses should override one or more methods to modify the behavior of the
+ * backing multiset as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Kevin Bourrillion
+ */
+public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
+ implements Multiset<E> {
+
+ @Override protected abstract Multiset<E> delegate();
+
+ public int count(Object element) {
+ return delegate().count(element);
+ }
+
+ public boolean add(E element, int occurrences) {
+ return delegate().add(element, occurrences);
+ }
+
+ public int remove(Object element, int occurrences) {
+ return delegate().remove(element, occurrences);
+ }
+
+ public int removeAllOccurrences(Object element) {
+ return delegate().removeAllOccurrences(element);
+ }
+
+ public Set<E> elementSet() {
+ return delegate().elementSet();
+ }
+
+ public Set<Entry<E>> entrySet() {
+ return delegate().entrySet();
+ }
+
+ @Override public boolean equals(Object obj) {
+ return (this == obj) || delegate().equals(obj);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingObject.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingObject.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingObject.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.io.Serializable;
+
+/**
+ * An abstract base class for implementing the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ * The {@link #delegate()} method must be overridden to return the instance
+ * being decorated.
+ *
+ * This class does <i>not</i> forward the {@code hashCode} and {@code equals}
+ * methods through to the backing object, but relies on {@code Object}'s
+ * implementation. This is necessary to preserve the symmetry of {@code equals}.
+ * Custom definitions of equality are usually based on an interface, such as
+ * {@code Set} or {@code List}, so that the implementation of {@code equals} can
+ * cast the object being tested for equality to the custom interface. {@code
+ * ForwardingObject} implements no such custom interfaces directly; they
+ * are implemented only in subclasses. Therefore, forwarding {@code equals}
+ * would break symmetry, as the forwarding object might consider itself equal to
+ * the object being tested, but the reverse could not be true. This behavior is
+ * consistent with the JDK's collection wrappers, such as
+ * {@link java.util.Collections#unmodifiableCollection}. Use an
+ * interface-specific subclass of {@code ForwardingObject}, such as {@link
+ * ForwardingList}, to preserve equality behavior, or override {@code equals}
+ * directly.
+ *
+ * <p>The {@code toString} method is forwarded to the delegate. Although this
+ * class does not implement {@link Serializable}, a serializable subclass may be
+ * created since this class has a parameter-less constructor.
+ *
+ * @author Mike Bostock
+ */
+public abstract class ForwardingObject {
+
+ /** Sole constructor. */
+ protected ForwardingObject() {}
+
+ /**
+ * Returns the backing delegate instance that methods are forwarded to.
+ * Abstract subclasses generally override the {@link ForwardingObject} method
+ * with an abstract method that has a more specific return type, such as
+ * {@link ForwardingSet#delegate}. Concrete subclasses override this method to
+ * supply the instance being decorated.
+ */
+ protected abstract Object delegate();
+
+ /**
+ * Returns the string representation generated by the delegate's
+ * {@code toString} method.
+ */
+ @Override public String toString() {
+ return delegate().toString();
+ }
+
+ /* No equals or hashCode. See class comments for details. */
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingQueue.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingQueue.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingQueue.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Queue;
+
+/**
+ * A queue which forwards all its method calls to another queue. Subclasses
+ * should override one or more methods to modify the behavior of the backing
+ * queue as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Mike Bostock
+ */
+public abstract class ForwardingQueue<E> extends ForwardingCollection<E>
+ implements Queue<E> {
+
+ @Override protected abstract Queue<E> delegate();
+
+ public boolean offer(E o) {
+ return delegate().offer(o);
+ }
+
+ public E poll() {
+ return delegate().poll();
+ }
+
+ public E remove() {
+ return delegate().remove();
+ }
+
+ public E peek() {
+ return delegate().peek();
+ }
+
+ public E element() {
+ return delegate().element();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSet.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSet.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSet.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Set;
+
+/**
+ * A set which forwards all its method calls to another set. Subclasses should
+ * override one or more methods to modify the behavior of the backing set as
+ * desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Kevin Bourrillion
+ */
+public abstract class ForwardingSet<E> extends ForwardingCollection<E>
+ implements Set<E> {
+
+ @Override protected abstract Set<E> delegate();
+
+ @Override public boolean equals(Object obj) {
+ return (this == obj) || delegate().equals(obj);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Comparator;
+import java.util.SortedMap;
+
+/**
+ * A sorted map which forwards all its method calls to another sorted map.
+ * Subclasses should override one or more methods to modify the behavior of
+ * the backing sorted map as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Mike Bostock
+ */
+public abstract class ForwardingSortedMap<K, V> extends ForwardingMap<K, V>
+ implements SortedMap<K, V> {
+
+ @Override protected abstract SortedMap<K, V> delegate();
+
+ public Comparator<? super K> comparator() {
+ return delegate().comparator();
+ }
+
+ public K firstKey() {
+ return delegate().firstKey();
+ }
+
+ public SortedMap<K, V> headMap(K toKey) {
+ return delegate().headMap(toKey);
+ }
+
+ public K lastKey() {
+ return delegate().lastKey();
+ }
+
+ public SortedMap<K, V> subMap(K fromKey, K toKey) {
+ return delegate().subMap(fromKey, toKey);
+ }
+
+ public SortedMap<K, V> tailMap(K fromKey) {
+ return delegate().tailMap(fromKey);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedSet.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedSet.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ForwardingSortedSet.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Comparator;
+import java.util.SortedSet;
+
+/**
+ * A sorted set which forwards all its method calls to another sorted set.
+ * Subclasses should override one or more methods to modify the behavior of the
+ * backing sorted set as desired per the <a
+ * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
+ *
+ * @see ForwardingObject
+ * @author Mike Bostock
+ */
+public abstract class ForwardingSortedSet<E> extends ForwardingSet<E>
+ implements SortedSet<E> {
+
+ @Override protected abstract SortedSet<E> delegate();
+
+ public Comparator<? super E> comparator() {
+ return delegate().comparator();
+ }
+
+ public E first() {
+ return delegate().first();
+ }
+
+ public SortedSet<E> headSet(E toElement) {
+ return delegate().headSet(toElement);
+ }
+
+ public E last() {
+ return delegate().last();
+ }
+
+ public SortedSet<E> subSet(E fromElement, E toElement) {
+ return delegate().subSet(fromElement, toElement);
+ }
+
+ public SortedSet<E> tailSet(E fromElement) {
+ return delegate().tailSet(fromElement);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashBiMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashBiMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashBiMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link BiMap} backed by two {@link HashMap} instances. This implementation
+ * allows null keys and values. A {@code HashBiMap} and its inverse are both
+ * serializable.
+ *
+ * @author Mike Bostock
+ */
+public final class HashBiMap<K, V> extends StandardBiMap<K, V> {
+ /**
+ * Constructs a new empty bimap with the default initial capacity (16).
+ */
+ public HashBiMap() {
+ super(new HashMap<K, V>(), new HashMap<V, K>());
+ }
+
+ /**
+ * Constructs a new empty bimap with the specified expected size.
+ *
+ * @param expectedSize the expected number of entries
+ * @throws IllegalArgumentException if the specified expected size is
+ * negative
+ */
+ public HashBiMap(int expectedSize) {
+ super(new HashMap<K, V>(Maps.capacity(expectedSize)),
+ new HashMap<V, K>(Maps.capacity(expectedSize)));
+ }
+
+ /**
+ * Constructs a new bimap containing initial values from {@code map}. The
+ * bimap is created with an initial capacity sufficient to hold the mappings
+ * in the specified map.
+ */
+ public HashBiMap(Map<? extends K, ? extends V> map) {
+ this(map.size());
+ putAll(map); // careful if we make this class non-final
+ }
+
+ // Override these two methods to show that keys and values may be null
+
+ @Override public V put(@Nullable K key, @Nullable V value) {
+ return super.put(key, value);
+ }
+
+ @Override public V forcePut(@Nullable K key, @Nullable V value) {
+ return super.forcePut(key, value);
+ }
+
+ /**
+ * @serialData the number of entries, first key, first value, second key,
+ * second value, and so on.
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMap(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setDelegates(new HashMap<K, V>(), new HashMap<V, K>());
+ Serialization.populateMap(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Implementation of {@link Multimap} using hash tables.
+ *
+ * <p>The multimap does not store duplicate key-value pairs. Adding a new
+ * key-value pair equal to an existing key-value pair has no effect.
+ *
+ * <p>Keys and values may be null. All optional multimap methods are supported,
+ * and all returned views are modifiable.
+ *
+ * <p>This class is not threadsafe when any concurrent operations update the
+ * multimap. Concurrent read operations will work correctly. To allow concurrent
+ * update operations, wrap your multimap with a call to {@link
+ * Multimaps#synchronizedSetMultimap}.
+ *
+ * @author Jared Levy
+ */
+public final class HashMultimap<K, V> extends StandardSetMultimap<K, V> {
+ /** Constructs an empty {@code HashMultimap}. */
+ public HashMultimap() {
+ super(new HashMap<K, Collection<V>>());
+ }
+
+ /**
+ * Constructs a {@code HashMultimap} with the same mappings as the specified
+ * {@code Multimap}. If a key-value mapping appears multiple times in the
+ * input multimap, it only appears once in the constructed multimap.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap.
+ * @see #putAll(Multimap)
+ */
+ public HashMultimap(Multimap<? extends K, ? extends V> multimap) {
+ super(new HashMap<K, Collection<V>>(
+ Maps.capacity(multimap.keySet().size())));
+ putAll(multimap);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Creates an empty {@code HashSet} for a collection of values for one key.
+ *
+ * @return a new {@code HashSet} containing a collection of values for one key
+ */
+ @Override Set<V> createCollection() {
+ return new HashSet<V>();
+ }
+
+ /**
+ * @serialData number of distinct keys, and then for each distinct key: the
+ * key, the number of values for that key, and the key's values
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMultimap(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setMap(new HashMap<K, Collection<V>>());
+ Serialization.populateMultimap(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/HashMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Multiset implementation backed by a {@link HashMap}.
+ *
+ * @author Kevin Bourrillion
+ * @author Jared Levy
+ */
+public final class HashMultiset<E> extends AbstractMapBasedMultiset<E> {
+
+ /**
+ * Creates a new empty {@code HashMultiset} using the default initial
+ * capacity.
+ */
+ public static <E> HashMultiset<E> create() {
+ return new HashMultiset<E>();
+ }
+
+ /**
+ * Creates a new empty {@code HashMultiset} with the specified expected number
+ * of distinct elements.
+ *
+ * @param distinctElements the expected number of distinct elements
+ * @throws IllegalArgumentException if {@code distinctElements} is negative
+ */
+ public static <E> HashMultiset<E> create(int distinctElements) {
+ return new HashMultiset<E>(distinctElements);
+ }
+
+ /**
+ * Creates a new {@code HashMultiset} containing the specified elements.
+ *
+ * @param elements the elements that the multiset should contain
+ */
+ public static <E> HashMultiset<E> create(Iterable<? extends E> elements) {
+ return new HashMultiset<E>(elements);
+ }
+
+ /**
+ * Constructs a new empty {@code HashMultiset} using the default initial
+ * capacity.
+ */
+ public HashMultiset() {
+ super(new HashMap<E, AtomicInteger>());
+ }
+
+ /**
+ * Constructs a new empty {@code HashMultiset} with the specified expected
+ * number of distinct elements.
+ *
+ * @param distinctElements the expected number of distinct elements
+ * @throws IllegalArgumentException if {@code distinctElements} is negative
+ */
+ private HashMultiset(int distinctElements) {
+ super(new HashMap<E, AtomicInteger>(Maps.capacity(distinctElements)));
+ }
+
+ /**
+ * Constructs a new {@code HashMultiset} containing the specified elements.
+ *
+ * @param elements the elements that the multiset should contain
+ */
+ private HashMultiset(Iterable<? extends E> elements) {
+ this(Multisets.inferDistinctElements(elements));
+ Iterables.addAll(this, elements); // careful if we make this class non-final
+ }
+
+ /**
+ * @serialData the number of distinct elements, the first element, its count,
+ * the second element, its count, and so on
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMultiset(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setBackingMap(new HashMap<E, AtomicInteger>());
+ Serialization.populateMultiset(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Hashing.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Hashing.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Hashing.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+
+/**
+ * Static methods for implementing hash-based collections.
+ *
+ * @author Kevin Bourrillion
+ * @author Jesse Wilson
+ */
+final class Hashing {
+ private Hashing() {}
+
+ /*
+ * This method was written by Doug Lea with assistance from members of JCP
+ * JSR-166 Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+ static int smear(int hashCode) {
+ hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12);
+ return hashCode ^ (hashCode >>> 7) ^ (hashCode >>> 4);
+ }
+
+ // We use power-of-2 tables, and this is the highest int that's a power of 2
+ private static final int MAX_TABLE_SIZE = 1 << 30;
+
+ // If the set has this many elements, it will "max out" the table size
+ private static final int CUTOFF = 1 << 29;
+
+ // Size the table to be at most 50% full, if possible
+ static int chooseTableSize(int setSize) {
+ if (setSize < CUTOFF) {
+ return Integer.highestOneBit(setSize) << 2;
+ }
+
+ // The table can't be completely full or we'll get infinite reprobes
+ checkArgument(setSize < MAX_TABLE_SIZE, "collection too large");
+ return MAX_TABLE_SIZE;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableBiMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableBiMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableBiMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Map;
+
+/**
+ * An immutable {@link BiMap} with reliable user-specified iteration order. Does
+ * not permit null keys or values. An {@code ImmutableBiMap} and its inverse
+ * have the same iteration ordering.
+ *
+ * <p>An instance of {@code ImmutableBiMap} contains its own data and will
+ * <i>never</i> change. {@code ImmutableBiMap} is convenient for
+ * {@code public static final} maps ("constant maps") and also lets you easily
+ * make a "defensive copy" of a bimap provided to your class by a caller.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
+ * it has no public or protected constructors. Thus, instances of this class are
+ * guaranteed to be immutable.
+ *
+ * @author Jared Levy
+ */
+public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K,V>
+ implements BiMap<K, V> {
+
+ private static final ImmutableBiMap<Object, Object> EMPTY_IMMUTABLE_BIMAP
+ = new EmptyBiMap();
+
+ /**
+ * Returns the empty bimap.
+ */
+ // Casting to any type is safe because the set will never hold any elements.
+ @SuppressWarnings("unchecked")
+ public static <K, V> ImmutableBiMap<K, V> of() {
+ return (ImmutableBiMap<K, V>) EMPTY_IMMUTABLE_BIMAP;
+ }
+
+ /**
+ * Returns an immutable bimap containing a single entry.
+ */
+ public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1) {
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys or values are added
+ */
+ public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1, K k2, V v2) {
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1, k2, v2));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys or values are added
+ */
+ public static <K, V> ImmutableBiMap<K, V> of(
+ K k1, V v1, K k2, V v2, K k3, V v3) {
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
+ k1, v1, k2, v2, k3, v3));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys or values are added
+ */
+ public static <K, V> ImmutableBiMap<K, V> of(
+ K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
+ k1, v1, k2, v2, k3, v3, k4, v4));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys or values are added
+ */
+ public static <K, V> ImmutableBiMap<K, V> of(
+ K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
+ k1, v1, k2, v2, k3, v3, k4, v4, k5, v5));
+ }
+
+ // looking for of() with > 5 entries? Use the builder instead.
+
+ /**
+ * Returns a new builder. The generated builder is equivalent to the builder
+ * created by the {@link Builder} constructor.
+ */
+ public static <K, V> Builder<K, V> builder() {
+ return new Builder<K, V>();
+ }
+
+ /**
+ * A builder for creating immutable bimap instances, especially {@code public
+ * static final} bimaps ("constant bimaps"). Example: <pre> {@code
+ *
+ * static final ImmutableBiMap<String, Integer> WORD_TO_INT =
+ * new ImmutableBiMap.Builder<String, Integer>()
+ * .put("one", 1)
+ * .put("two", 2)
+ * .put("three", 3)
+ * .build();}</pre>
+ *
+ * For <i>small</i> immutable bimaps, the {@code ImmutableBiMap.of()} methods
+ * are even more convenient.
+ *
+ * <p>Builder instances can be reused - it is safe to call {@link #build}
+ * multiple times to build multiple bimaps in series. Each bimap is a superset
+ * of the bimaps created before it.
+ */
+ public static final class Builder<K, V> extends ImmutableMap.Builder<K, V> {
+
+ /**
+ * Creates a new builder. The returned builder is equivalent to the builder
+ * generated by {@link ImmutableBiMap#builder}.
+ */
+ public Builder() {}
+
+ /**
+ * Associates {@code key} with {@code value} in the built bimap. Duplicate
+ * keys or values are not allowed, and will cause {@link #build} to fail.
+ */
+ @Override public Builder<K, V> put(K key, V value) {
+ super.put(key, value);
+ return this;
+ }
+
+ /**
+ * Associates all of {@code map's} keys and values in the built bimap.
+ * Duplicate keys or values are not allowed, and will cause {@link #build}
+ * to fail.
+ *
+ * @throws NullPointerException if any key or value in {@code map} is null
+ */
+ @Override public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
+ super.putAll(map);
+ return this;
+ }
+
+ /**
+ * Returns a newly-created immutable bimap.
+ *
+ * @throws IllegalArgumentException if duplicate keys or values were added
+ */
+ @Override public ImmutableBiMap<K, V> build() {
+ ImmutableMap<K, V> map = super.build();
+ if (map.isEmpty()) {
+ return of();
+ }
+ return new RegularImmutableBiMap<K, V>(super.build());
+ }
+ }
+
+ /**
+ * Returns an immutable bimap containing the same entries as {@code map}. If
+ * {@code map} somehow contains entries with duplicate keys (for example, if
+ * it is a {@code SortedMap} whose comparator is not <i>consistent with
+ * equals</i>), the results of this method are undefined.
+ *
+ * <p><b>Note:</b> If {@code map} is an {@code ImmutableBiMap}, the given map
+ * itself will be returned.
+ *
+ * @throws IllegalArgumentException if two keys have the same value
+ * @throws NullPointerException if any key or value in {@code map} is null
+ */
+ public static <K, V> ImmutableBiMap<K, V> copyOf(
+ Map<? extends K, ? extends V> map) {
+ if (map instanceof ImmutableBiMap) {
+ @SuppressWarnings("unchecked") // safe since map is not writable
+ ImmutableBiMap<K, V> bimap = (ImmutableBiMap<K, V>) map;
+ return bimap;
+ }
+
+ if (map.isEmpty()) {
+ return of();
+ }
+
+ ImmutableMap<K, V> immutableMap = ImmutableMap.copyOf(map);
+ return new RegularImmutableBiMap<K, V>(immutableMap);
+ }
+
+ abstract ImmutableMap<K, V> delegate();
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The inverse of an {@code ImmutableBiMap} is another
+ * {@code ImmutableBiMap}.
+ */
+ public abstract ImmutableBiMap<V, K> inverse();
+
+ @Override public boolean containsKey(@Nullable Object key) {
+ return delegate().containsKey(key);
+ }
+
+ @Override public boolean containsValue(@Nullable Object value) {
+ return inverse().containsKey(value);
+ }
+
+ @Override public ImmutableSet<Entry<K, V>> entrySet() {
+ return delegate().entrySet();
+ }
+
+ @Override public V get(@Nullable Object key) {
+ return delegate().get(key);
+ }
+
+ @Override public ImmutableSet<K> keySet() {
+ return delegate().keySet();
+ }
+
+ /**
+ * Returns an immutable set of the values in this map. The values are in the
+ * same order as the parameters used to build this map.
+ */
+ @Override public ImmutableSet<V> values() {
+ return inverse().keySet();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the bimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public V forcePut(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isEmpty() {
+ return delegate().isEmpty();
+ }
+
+ public int size() {
+ return delegate().size();
+ }
+
+ @Override public boolean equals(@Nullable Object o) {
+ return (o == this) || delegate().equals(o);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+
+ @Override public String toString() {
+ return delegate().toString();
+ }
+
+ @Override Object writeReplace() {
+ return this; // don't use the ImmutableMap serialized form
+ }
+
+ /** Bimap with no mappings. */
+ private static class EmptyBiMap extends ImmutableBiMap<Object, Object> {
+ @Override ImmutableMap<Object, Object> delegate() {
+ return ImmutableMap.of();
+ }
+ @Override public ImmutableBiMap<Object, Object> inverse() {
+ return this;
+ }
+ Object readResolve() {
+ return EMPTY_IMMUTABLE_BIMAP; // preserve singleton property
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** Bimap with one or more mappings. */
+ private static class RegularImmutableBiMap<K, V>
+ extends ImmutableBiMap<K, V> {
+ final ImmutableMap<K, V> delegate;
+ final ImmutableBiMap<V, K> inverse;
+
+ RegularImmutableBiMap(ImmutableMap<K, V> delegate) {
+ this.delegate = delegate;
+
+ ImmutableMap.Builder<V, K> builder = ImmutableMap.builder();
+ for (Entry<K, V> entry : delegate.entrySet()) {
+ builder.put(entry.getValue(), entry.getKey());
+ }
+ ImmutableMap<V, K> backwardMap = builder.build();
+ this.inverse = new RegularImmutableBiMap<V, K>(backwardMap, this);
+ }
+
+ RegularImmutableBiMap(ImmutableMap<K, V> delegate,
+ ImmutableBiMap<V, K> inverse) {
+ this.delegate = delegate;
+ this.inverse = inverse;
+ }
+
+ @Override ImmutableMap<K, V> delegate() {
+ return delegate;
+ }
+
+ @Override public ImmutableBiMap<V, K> inverse() {
+ return inverse;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableCollection.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableCollection.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableCollection.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * An immutable collection. Does not permit null elements.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed
+ * outside of this package as it has no public or protected constructors. Thus,
+ * instances of this type are guaranteed to be immutable.
+ *
+ * @author Jesse Wilson
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public abstract class ImmutableCollection<E>
+ implements Collection<E>, Serializable {
+ static final ImmutableCollection<Object> EMPTY_IMMUTABLE_COLLECTION
+ = new EmptyImmutableCollection();
+
+ ImmutableCollection() {}
+
+ public Object[] toArray() {
+ Object[] newArray = new Object[size()];
+ return toArray(newArray);
+ }
+
+ public <T> T[] toArray(T[] other) {
+ int size = size();
+ if (other.length < size) {
+ other = ObjectArrays.newArray(other, size);
+ } else if (other.length > size) {
+ other[size] = null;
+ }
+ int index = 0;
+ for (E element : this) {
+ /*
+ * Sleazy fake cast. However, if element is not a T, then the very next
+ * line must fail with an ArrayStoreException, so we should be safe.
+ */
+ @SuppressWarnings("unchecked")
+ T elementAsT = (T) element;
+
+ other[index++] = elementAsT;
+ }
+ return other;
+ }
+
+ public boolean contains(@Nullable Object object) {
+ if (object == null) {
+ return false;
+ }
+ for (E element : this) {
+ if (element.equals(object)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean containsAll(Collection<?> targets) {
+ for (Object target : targets) {
+ if (!contains(target)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ @Override public String toString() {
+ StringBuilder sb = new StringBuilder(size() * 16);
+ sb.append('[');
+ Iterator<E> i = iterator();
+ if (i.hasNext()) {
+ sb.append(i.next());
+ }
+ while (i.hasNext()) {
+ sb.append(", ");
+ sb.append(i.next());
+ }
+ return sb.append(']').toString();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean add(E e) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean remove(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean addAll(Collection<? extends E> newElements) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean removeAll(Collection<?> oldElements) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean retainAll(Collection<?> elementsToKeep) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ private static class EmptyImmutableCollection
+ extends ImmutableCollection<Object> {
+ public int size() {
+ return 0;
+ }
+
+ @Override public boolean isEmpty() {
+ return true;
+ }
+
+ @Override public boolean contains(@Nullable Object object) {
+ return false;
+ }
+
+ public Iterator<Object> iterator() {
+ return Iterators.emptyIterator();
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.EMPTY_ARRAY;
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ if (array.length > 0) {
+ array[0] = null;
+ }
+ return array;
+ }
+ }
+
+ private static class ArrayImmutableCollection<E>
+ extends ImmutableCollection<E> {
+ private final E[] elements;
+
+ ArrayImmutableCollection(E[] elements) {
+ this.elements = elements;
+ }
+
+ public int size() {
+ return elements.length;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ public Iterator<E> iterator() {
+ return Iterators.forArray(elements);
+ }
+ }
+
+ /*
+ * Serializes ImmutableCollections as their logical contents. This ensures
+ * that implementation types do not leak into the serialized representation.
+ */
+ private static class SerializedForm implements Serializable {
+ final Object[] elements;
+ SerializedForm(Object[] elements) {
+ this.elements = elements;
+ }
+ Object readResolve() {
+ return elements.length == 0
+ ? EMPTY_IMMUTABLE_COLLECTION
+ : new ArrayImmutableCollection<Object>(elements.clone());
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ Object writeReplace() {
+ return new SerializedForm(toArray());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableList.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableList.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableList.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.RandomAccess;
+
+/**
+ * A high-performance, immutable, random-access {@code List} implementation.
+ * Does not permit null elements.
+ *
+ * <p>Unlike {@link Collections#unmodifiableList}, which is a <i>view</i> of a
+ * separate collection that can still change, an instance of {@code
+ * ImmutableList} contains its own private data and will <i>never</i> change.
+ * {@code ImmutableList} is convenient for {@code public static final} lists
+ * ("constant lists") and also lets you easily make a "defensive copy" of a list
+ * provided to your class by a caller.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
+ * it has no public or protected constructors. Thus, instances of this type are
+ * guaranteed to be immutable.
+ *
+ * @see ImmutableMap
+ * @see ImmutableSet
+ * @author Kevin Bourrillion
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public abstract class ImmutableList<E> extends ImmutableCollection<E>
+ implements List<E>, RandomAccess {
+ private static final ImmutableList<?> EMPTY_IMMUTABLE_LIST
+ = new EmptyImmutableList();
+
+ /**
+ * Returns the empty immutable list. This set behaves and performs comparably
+ * to {@link Collections#emptyList}, and is preferable mainly for consistency
+ * and maintainability of your code.
+ */
+ // Casting to any type is safe because the list will never hold any elements.
+ @SuppressWarnings("unchecked")
+ public static <E> ImmutableList<E> of() {
+ return (ImmutableList<E>) EMPTY_IMMUTABLE_LIST;
+ }
+
+ /**
+ * Returns an immutable list containing a single element. This list behaves
+ * and performs comparably to {@link Collections#singleton}, but will not
+ * accept a null element. It is preferable mainly for consistency and
+ * maintainability of your code.
+ *
+ * @throws NullPointerException if {@code element} is null
+ */
+ public static <E> ImmutableList<E> of(E element) {
+ // TODO: evaluate a specialized SingletonImmutableList
+ return new RegularImmutableList<E>(copyIntoArray(element));
+ }
+
+ // TODO: Add similar overloadings to ImmutableSet and ImmutableSortedSet
+
+ /**
+ * Returns an immutable list containing the given elements, in order.
+ *
+ * @throws NullPointerException if any element is null
+ */
+ public static <E> ImmutableList<E> of(E e1, E e2) {
+ return new RegularImmutableList<E>(copyIntoArray(e1, e2));
+ }
+
+ /**
+ * Returns an immutable list containing the given elements, in order.
+ *
+ * @throws NullPointerException if any element is null
+ */
+ public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
+ return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3));
+ }
+
+ /**
+ * Returns an immutable list containing the given elements, in order.
+ *
+ * @throws NullPointerException if any element is null
+ */
+ public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
+ return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3, e4));
+ }
+
+ /**
+ * Returns an immutable list containing the given elements, in order.
+ *
+ * @throws NullPointerException if any element is null
+ */
+ public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
+ return new RegularImmutableList<E>(copyIntoArray(e1, e2, e3, e4, e5));
+ }
+
+ /**
+ * Returns an immutable list containing the given elements, in order.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableList<E> of(E... elements) {
+ return (elements.length == 0)
+ ? ImmutableList.<E>of()
+ : new RegularImmutableList<E>(copyIntoArray(elements));
+ }
+
+ /**
+ * Returns an immutable list containing the given elements, in order. Note
+ * that if {@code list} is a {@code List<String>}, then {@code
+ * ImmutableList.copyOf(list)} returns an {@code ImmutableList<String>}
+ * containing each of the strings in {@code list}, while
+ * ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>}
+ * containing one element (the given list itself).
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
+ * is an {@code ImmutableList}, no copy will actually be performed, and the
+ * given list itself will be returned.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
+ if (elements instanceof ImmutableList) {
+ @SuppressWarnings("unchecked") // all supported methods are covariant
+ ImmutableList<E> list = (ImmutableList<E>) elements;
+ return list;
+ }
+ return copyOfInternal(Collections2.toCollection(elements));
+ }
+
+ /**
+ * Returns an immutable list containing the given elements, in order.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
+ return copyOfInternal(Lists.newArrayList(elements));
+ }
+
+ private static <E> ImmutableList<E> copyOfInternal(Collection<?> collection) {
+ // TODO: Support concurrent collections that change while this method is
+ // running.
+ int size = collection.size();
+ return (size == 0)
+ ? ImmutableList.<E>of()
+ : new RegularImmutableList<E>(copyIntoArray(collection, size));
+ }
+
+ private ImmutableList() {}
+
+ // Mark these two methods with @Nullable
+
+ public abstract int indexOf(@Nullable Object object);
+
+ public abstract int lastIndexOf(@Nullable Object object);
+
+ // constrain the return type to ImmutableList<E>
+
+ /**
+ * Returns an immutable list of the elements between the specified {@code
+ * fromIndex}, inclusive, and {@code toIndex}, exclusive. (If {@code
+ * fromIndex} and {@code toIndex} are equal, the empty immutable list is
+ * returned.)
+ */
+ public abstract ImmutableList<E> subList(int fromIndex, int toIndex);
+
+ /**
+ * Guaranteed to throw an exception and leave the list unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean addAll(int index, Collection<? extends E> newElements) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the list unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final E set(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the list unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final void add(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the list unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final E remove(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ private static final class EmptyImmutableList extends ImmutableList<Object> {
+ public int size() {
+ return 0;
+ }
+
+ @Override public boolean isEmpty() {
+ return true;
+ }
+
+ @Override public boolean contains(Object target) {
+ return false;
+ }
+
+ public Iterator<Object> iterator() {
+ return Iterators.emptyIterator();
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.EMPTY_ARRAY;
+ }
+
+ @Override public <T> T[] toArray(T[] a) {
+ if (a.length > 0) {
+ a[0] = null;
+ }
+ return a;
+ }
+
+ public Object get(int index) {
+ throw new IndexOutOfBoundsException(
+ "Invalid index: " + index + ", list size is 0");
+ }
+
+ @Override public int indexOf(Object target) {
+ return -1;
+ }
+
+ @Override public int lastIndexOf(Object target) {
+ return -1;
+ }
+
+ @Override public ImmutableList<Object> subList(int fromIndex, int toIndex) {
+ if (fromIndex != 0 || toIndex != 0) {
+ throw new IndexOutOfBoundsException("Invalid range: " + fromIndex
+ + ".." + toIndex + ", list size is 0");
+ }
+ return this;
+ }
+
+ public ListIterator<Object> listIterator() {
+ return Iterators.emptyListIterator();
+ }
+
+ public ListIterator<Object> listIterator(int start) {
+ if (start != 0) {
+ throw new IndexOutOfBoundsException(
+ "Invalid index: " + start + ", list size is 0");
+ }
+ return Iterators.emptyListIterator();
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ return targets.isEmpty();
+ }
+
+ @Override public boolean equals(Object object) {
+ return object == this
+ || (object instanceof List && ((List<?>) object).isEmpty());
+ }
+
+ @Override public int hashCode() {
+ return 1;
+ }
+
+ @Override public String toString() {
+ return "[]";
+ }
+
+ private Object readResolve() {
+ return EMPTY_IMMUTABLE_LIST;
+ }
+ }
+
+ private static final class RegularImmutableList<E> extends ImmutableList<E> {
+ private final int offset;
+ private final int size;
+ private final Object[] array;
+
+ private RegularImmutableList(Object[] array, int offset, int size) {
+ this.offset = offset;
+ this.size = size;
+ this.array = array;
+ }
+
+ private RegularImmutableList(Object[] array) {
+ this(array, 0, array.length);
+ }
+
+ public int size() {
+ return size;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public boolean contains(Object target) {
+ return indexOf(target) != -1;
+ }
+
+ // The fake cast to E is safe because the creation methods only allow E's
+ @SuppressWarnings("unchecked")
+ public Iterator<E> iterator() {
+ return (Iterator<E>) Iterators.forArray(array, offset, size);
+ }
+
+ @Override public Object[] toArray() {
+ Object[] newArray = new Object[size()];
+ System.arraycopy(array, offset, newArray, 0, size);
+ return newArray;
+ }
+
+ @Override public <T> T[] toArray(T[] other) {
+ if (other.length < size) {
+ other = ObjectArrays.newArray(other, size);
+ } else if (other.length > size) {
+ other[size] = null;
+ }
+ System.arraycopy(array, offset, other, 0, size);
+ return other;
+ }
+
+ // The fake cast to E is safe because the creation methods only allow E's
+ @SuppressWarnings("unchecked")
+ public E get(int index) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException(
+ "Invalid index: " + index + ", list size is " + size);
+ }
+ return (E) array[index + offset];
+ }
+
+ @Override public int indexOf(Object target) {
+ if (target != null) {
+ for (int i = offset; i < offset + size; i++) {
+ if (array[i].equals(target)) {
+ return i - offset;
+ }
+ }
+ }
+ return -1;
+ }
+
+ @Override public int lastIndexOf(Object target) {
+ if (target != null) {
+ for (int i = offset + size - 1; i >= offset; i--) {
+ if (array[i].equals(target)) {
+ return i - offset;
+ }
+ }
+ }
+ return -1;
+ }
+
+ @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
+ if (fromIndex < 0 || toIndex > size || fromIndex > toIndex) {
+ throw new IndexOutOfBoundsException("Invalid range: " + fromIndex
+ + ".." + toIndex + ", list size is " + size);
+ }
+
+ return (fromIndex == toIndex)
+ ? ImmutableList.<E>of()
+ : new RegularImmutableList<E>(
+ array, offset + fromIndex, toIndex - fromIndex);
+ }
+
+ public ListIterator<E> listIterator() {
+ return listIterator(0);
+ }
+
+ public ListIterator<E> listIterator(final int start) {
+ if ((start < 0) || (start > size)) {
+ throw new IndexOutOfBoundsException(
+ "Invalid index: " + start + ", list size is " + size);
+ }
+
+ return new ListIterator<E>() {
+ int index = start;
+
+ public boolean hasNext() {
+ return index < size;
+ }
+ public boolean hasPrevious() {
+ return index > 0;
+ }
+
+ public int nextIndex() {
+ return index;
+ }
+ public int previousIndex() {
+ return index - 1;
+ }
+
+ public E next() {
+ E result;
+ try {
+ result = get(index);
+ } catch (IndexOutOfBoundsException rethrown) {
+ throw new NoSuchElementException();
+ }
+ index++;
+ return result;
+ }
+ public E previous() {
+ E result;
+ try {
+ result = get(index - 1);
+ } catch (IndexOutOfBoundsException rethrown) {
+ throw new NoSuchElementException();
+ }
+ index--;
+ return result;
+ }
+
+ public void set(E o) {
+ throw new UnsupportedOperationException();
+ }
+ public void add(E o) {
+ throw new UnsupportedOperationException();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof List)) {
+ return false;
+ }
+
+ List<?> that = (List<?>) object;
+ if (that.size() != size()) {
+ return false;
+ }
+
+ int index = offset;
+ if (object instanceof RegularImmutableList) {
+ RegularImmutableList<?> other = (RegularImmutableList<?>) object;
+ for (int i = other.offset; i < other.offset + other.size; i++) {
+ if (!array[index++].equals(other.array[i])) {
+ return false;
+ }
+ }
+ } else {
+ for (Object element : that) {
+ if (!array[index++].equals(element)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override public int hashCode() {
+ // not caching hash code since it could change if the elements are mutable
+ // in a way that modifies their hash codes
+ int hashCode = 1;
+ for (int i = offset; i < offset + size; i++) {
+ hashCode = 31 * hashCode + array[i].hashCode();
+ }
+ return hashCode;
+ }
+
+ @Override public String toString() {
+ StringBuilder sb = new StringBuilder(size() * 16);
+ sb.append('[').append(array[offset]);
+ for (int i = offset + 1; i < offset + size; i++) {
+ sb.append(", ").append(array[i]);
+ }
+ return sb.append(']').toString();
+ }
+ }
+
+ private static Object[] copyIntoArray(Object... source) {
+ Object[] array = new Object[source.length];
+ int index = 0;
+ for (Object element : source) {
+ if (element == null) {
+ throw new NullPointerException("at index " + index);
+ }
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static Object[] copyIntoArray(Iterable<?> source, int size) {
+ Object[] array = new Object[size];
+ int index = 0;
+ for (Object element : source) {
+ if (element == null) {
+ throw new NullPointerException("at index " + index);
+ }
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ /*
+ * Serializes ImmutableLists as their logical contents. This ensures that
+ * implementation types do not leak into the serialized representation.
+ */
+ private static class SerializedForm implements Serializable {
+ final Object[] elements;
+ SerializedForm(Object[] elements) {
+ this.elements = elements;
+ }
+ Object readResolve() {
+ return of(elements);
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException {
+ throw new InvalidObjectException("Use SerializedForm");
+ }
+
+ @Override Object writeReplace() {
+ return new SerializedForm(toArray());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,772 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import static org.richfaces.collections.collect.Iterables.getOnlyElement;
+
+import org.richfaces.collections.base.Join;
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.collect.ImmutableSet.ArrayImmutableSet;
+import org.richfaces.collections.collect.ImmutableSet.TransformedImmutableSet;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * An immutable, hash-based {@link Map} with reliable user-specified iteration
+ * order. Does not permit null keys or values.
+ *
+ * <p>Unlike {@link Collections#unmodifiableMap}, which is a <i>view</i> of a
+ * separate map which can still change, an instance of {@code ImmutableMap}
+ * contains its own data and will <i>never</i> change. {@code ImmutableMap} is
+ * convenient for {@code public static final} maps ("constant maps") and also
+ * lets you easily make a "defensive copy" of a map provided to your class by a
+ * caller.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
+ * it has no public or protected constructors. Thus, instances of this class are
+ * guaranteed to be immutable.
+ *
+ * @see ImmutableList
+ * @see ImmutableSet
+ * @author Jesse Wilson
+ * @author Kevin Bourrillion
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public abstract class ImmutableMap<K, V>
+ implements ConcurrentMap<K, V>, Serializable {
+ private static final ImmutableMap<?, ?> EMPTY_IMMUTABLE_MAP
+ = new EmptyImmutableMap();
+
+ // TODO: restore prebuilder API? optimize, compare performance to HashMap
+
+ /**
+ * Returns the empty map. This map behaves and performs comparably to
+ * {@link Collections#emptyMap}, and is preferable mainly for consistency
+ * and maintainability of your code.
+ */
+ // Casting to any type is safe because the set will never hold any elements.
+ @SuppressWarnings("unchecked")
+ public static <K, V> ImmutableMap<K, V> of() {
+ return (ImmutableMap<K, V>) EMPTY_IMMUTABLE_MAP;
+ }
+
+ /**
+ * Returns an immutable map containing a single entry. This map behaves and
+ * performs comparably to {@link Collections#singletonMap} but will not accept
+ * a null key or value. It is preferable mainly for consistency and
+ * maintainability of your code.
+ */
+ public static <K, V> ImmutableMap<K, V> of(K k1, V v1) {
+ return new SingletonImmutableMap<K, V>(
+ checkNotNull(k1), checkNotNull(v1));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys are added
+ */
+ public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2) {
+ return new RegularImmutableMap<K, V>(entryOf(k1, v1), entryOf(k2, v2));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys are added
+ */
+ public static <K, V> ImmutableMap<K, V> of(
+ K k1, V v1, K k2, V v2, K k3, V v3) {
+ return new RegularImmutableMap<K, V>(
+ entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys are added
+ */
+ public static <K, V> ImmutableMap<K, V> of(
+ K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
+ return new RegularImmutableMap<K, V>(
+ entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4));
+ }
+
+ /**
+ * Returns an immutable map containing the given entries, in order.
+ *
+ * @throws IllegalArgumentException if duplicate keys are added
+ */
+ public static <K, V> ImmutableMap<K, V> of(
+ K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
+ return new RegularImmutableMap<K, V>(entryOf(k1, v1),
+ entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5));
+ }
+
+ // looking for of() with > 5 entries? Use the builder instead.
+
+ /**
+ * Returns a new builder. The generated builder is equivalent to the builder
+ * created by the {@link Builder} constructor.
+ */
+ public static <K, V> Builder<K, V> builder() {
+ return new Builder<K, V>();
+ }
+
+ /**
+ * Verifies that {@code key} and {@code value} are non-null, and returns a new
+ * entry with those values.
+ */
+ private static <K, V> Entry<K, V> entryOf(K key, V value) {
+ return Maps.immutableEntry(checkNotNull(key), checkNotNull(value));
+ }
+
+ /**
+ * A builder for creating immutable map instances, especially {@code public
+ * static final} maps ("constant maps"). Example: <pre> {@code
+ *
+ * static final ImmutableMap<String, Integer> WORD_TO_INT =
+ * new ImmutableMap.Builder<String, Integer>()
+ * .put("one", 1)
+ * .put("two", 2)
+ * .put("three", 3)
+ * .build();}</pre>
+ *
+ * For <i>small</i> immutable maps, the {@code ImmutableMap.of()} methods are
+ * even more convenient.
+ *
+ * <p>Builder instances can be reused - it is safe to call {@link #build}
+ * multiple times to build multiple maps in series. Each map is a superset of
+ * the maps created before it.
+ */
+ public static class Builder<K, V> {
+ final List<Entry<K, V>> entries = Lists.newArrayList();
+
+ /**
+ * Creates a new builder. The returned builder is equivalent to the builder
+ * generated by {@link ImmutableMap#builder}.
+ */
+ public Builder() {}
+
+ /**
+ * Associates {@code key} with {@code value} in the built map. Duplicate
+ * keys are not allowed, and will cause {@link #build} to fail.
+ */
+ public Builder<K, V> put(K key, V value) {
+ entries.add(entryOf(key, value));
+ return this;
+ }
+
+ /**
+ * Associates all of {@code map's} keys and values in the built map.
+ * Duplicate keys are not allowed, and will cause {@link #build} to fail.
+ *
+ * @throws NullPointerException if any key or value in {@code map} is null
+ */
+ public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
+ for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
+ put(entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+
+ // TODO: Should build() and the ImmutableBiMap version throw an
+ // IllegalStateException instead?
+
+ /**
+ * Returns a newly-created immutable map.
+ *
+ * @throws IllegalArgumentException if duplicate keys were added
+ */
+ public ImmutableMap<K, V> build() {
+ return fromEntryList(entries);
+ }
+
+ private static <K, V> ImmutableMap<K, V> fromEntryList(
+ List<Entry<K, V>> entries) {
+ int size = entries.size();
+ switch (size) {
+ case 0:
+ return of();
+ case 1:
+ return new SingletonImmutableMap<K, V>(getOnlyElement(entries));
+ default:
+ Entry<?, ?>[] entryArray
+ = entries.toArray(new Entry<?, ?>[entries.size()]);
+ return new RegularImmutableMap<K, V>(entryArray);
+ }
+ }
+ }
+
+ /**
+ * Returns an immutable map containing the same entries as {@code map}. If
+ * {@code map} somehow contains entries with duplicate keys (for example, if
+ * it is a {@code SortedMap} whose comparator is not <i>consistent with
+ * equals</i>), the results of this method are undefined.
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if {@code map} is an
+ * {@code ImmutableMap}, no copy will actually be performed, and the given map
+ * itself will be returned.
+ *
+ * @throws NullPointerException if any key or value in {@code map} is null
+ */
+ public static <K, V> ImmutableMap<K, V> copyOf(
+ Map<? extends K, ? extends V> map) {
+ if (map instanceof ImmutableMap) {
+ @SuppressWarnings("unchecked") // safe since map is not writable
+ ImmutableMap<K, V> kvMap = (ImmutableMap<K, V>) map;
+ return kvMap;
+ }
+
+ int size = map.size();
+ switch (size) {
+ case 0:
+ return of();
+ case 1:
+ Map.Entry<? extends K, ? extends V> loneEntry
+ = getOnlyElement(map.entrySet());
+ /*
+ * Must cast next line to (K) and (V) to avoid returning an
+ * ImmutableMap<? extends K, ? extends V>, which is incompatible
+ * with the return type ImmutableMap<K, V>. (Eclipse will complain
+ * mightily about this line if there's no cast.)
+ */
+ return of((K) loneEntry.getKey(), (V) loneEntry.getValue());
+ default:
+ Entry<?, ?>[] array = new Entry<?, ?>[size];
+ int i = 0;
+ for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
+ /*
+ * See comment above re: <? extends K, ? extends V> to <K, V>.
+ */
+ array[i++] = entryOf((K) entry.getKey(), (V) entry.getValue());
+ }
+ return new RegularImmutableMap<K, V>(array);
+ }
+ }
+
+ ImmutableMap() {}
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final V put(K k, V v) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final V remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final V putIfAbsent(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean remove(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final boolean replace(K key, V oldValue, V newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final V replace(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final void putAll(Map<? extends K, ? extends V> map) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the map unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ // Overriding to mark it Nullable
+ public abstract boolean containsKey(@Nullable Object key);
+
+ // Overriding to mark it Nullable
+ public abstract boolean containsValue(@Nullable Object value);
+
+ // Overriding to mark it Nullable
+ public abstract V get(@Nullable Object key);
+
+ /**
+ * Returns an immutable set of the mappings in this map. The entries are in
+ * the same order as the parameters used to build this map.
+ */
+ public abstract ImmutableSet<Entry<K, V>> entrySet();
+
+ /**
+ * Returns an immutable set of the keys in this map. These keys are in
+ * the same order as the parameters used to build this map.
+ */
+ public abstract ImmutableSet<K> keySet();
+
+ /**
+ * Returns an immutable collection of the values in this map. The values are
+ * in the same order as the parameters used to build this map.
+ */
+ public abstract ImmutableCollection<V> values();
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) object;
+ return entrySet().equals(map.entrySet());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ // not caching hash code since it could change if map values are mutable
+ // in a way that modifies their hash codes
+ return entrySet().hashCode();
+ }
+
+ @Override public String toString() {
+ StringBuilder result = new StringBuilder(size() * 16).append('{');
+ Join.join(result, ", ", entrySet());
+ return result.append('}').toString();
+ }
+
+ private static final class EmptyImmutableMap
+ extends ImmutableMap<Object, Object> {
+
+ @Override public Object get(Object key) {
+ return null;
+ }
+
+ public int size() {
+ return 0;
+ }
+
+ public boolean isEmpty() {
+ return true;
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return false;
+ }
+
+ @Override public boolean containsValue(Object value) {
+ return false;
+ }
+
+ @Override public ImmutableSet<Entry<Object, Object>> entrySet() {
+ return ImmutableSet.of();
+ }
+
+ @Override public ImmutableSet<Object> keySet() {
+ return ImmutableSet.of();
+ }
+
+ @Override public ImmutableCollection<Object> values() {
+ return ImmutableCollection.EMPTY_IMMUTABLE_COLLECTION;
+ }
+
+ @Override public boolean equals(Object object) {
+ return object == this
+ || (object instanceof Map && ((Map<?, ?>) object).isEmpty());
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public String toString() {
+ return "{}";
+ }
+ }
+
+ private static final class SingletonImmutableMap<K, V>
+ extends ImmutableMap<K, V> {
+ private transient final K singleKey;
+ private transient final V singleValue;
+ private transient Entry<K, V> entry;
+
+ private SingletonImmutableMap(K singleKey, V singleValue) {
+ this.singleKey = singleKey;
+ this.singleValue = singleValue;
+ }
+
+ private SingletonImmutableMap(Entry<K, V> entry) {
+ this.entry = entry;
+ this.singleKey = entry.getKey();
+ this.singleValue = entry.getValue();
+ }
+
+ private Entry<K, V> entry() {
+ Entry<K, V> e = entry;
+ return (e == null)
+ ? (entry = Maps.immutableEntry(singleKey, singleValue)) : e;
+ }
+
+ @Override public V get(Object key) {
+ return singleKey.equals(key) ? singleValue : null;
+ }
+
+ public int size() {
+ return 1;
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return singleKey.equals(key);
+ }
+
+ @Override public boolean containsValue(Object value) {
+ return singleValue.equals(value);
+ }
+
+ private transient ImmutableSet<Entry<K, V>> entrySet;
+
+ @Override public ImmutableSet<Entry<K, V>> entrySet() {
+ ImmutableSet<Entry<K, V>> es = entrySet;
+ return (es == null) ? (entrySet = ImmutableSet.of(entry())) : es;
+ }
+
+ private transient ImmutableSet<K> keySet;
+
+ @Override public ImmutableSet<K> keySet() {
+ ImmutableSet<K> ks = keySet;
+ return (ks == null) ? (keySet = ImmutableSet.of(singleKey)) : ks;
+ }
+
+ private transient ImmutableCollection<V> values;
+
+ @Override public ImmutableCollection<V> values() {
+ ImmutableCollection<V> v = values;
+ return (v == null) ? (values = new Values<V>(singleValue)) : v;
+ }
+
+ private static class Values<V> extends ImmutableCollection<V> {
+ final V singleValue;
+
+ Values(V singleValue) {
+ this.singleValue = singleValue;
+ }
+
+ @Override public boolean contains(Object object) {
+ return singleValue.equals(object);
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ public int size() {
+ return 1;
+ }
+
+ public Iterator<V> iterator() {
+ return Iterators.singletonIterator(singleValue);
+ }
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) object;
+ return map.size() == 1 && map.entrySet().contains(entry());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return singleKey.hashCode() ^ singleValue.hashCode();
+ }
+
+ @Override public String toString() {
+ return new StringBuilder()
+ .append('{')
+ .append(singleKey.toString())
+ .append('=')
+ .append(singleValue.toString())
+ .append('}')
+ .toString();
+ }
+ }
+
+ private static final class RegularImmutableMap<K, V>
+ extends ImmutableMap<K, V> {
+ private transient final Entry<K, V>[] entries; // entries in insertion order
+ private transient final Object[] table; // alternating keys and values
+ // 'and' with an int then shift to get a table index
+ private transient final int mask;
+ private transient final int keySetHashCode;
+
+ private RegularImmutableMap(Entry<?, ?>... entries) {
+ // each of our 6 callers carefully put only Entry<K, V>s into the array!
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] tmp = (Entry<K, V>[]) entries;
+ this.entries = tmp;
+
+ int tableSize = Hashing.chooseTableSize(entries.length);
+ table = new Object[tableSize * 2];
+ mask = tableSize - 1;
+
+ int keySetHashCodeMutable = 0;
+ for (Entry<K, V> entry : this.entries) {
+ K key = entry.getKey();
+ int keyHashCode = key.hashCode();
+ for (int i = Hashing.smear(keyHashCode); true; i++) {
+ int index = (i & mask) * 2;
+ Object existing = table[index];
+ if (existing == null) {
+ V value = entry.getValue();
+ table[index] = key;
+ table[index + 1] = value;
+ keySetHashCodeMutable += keyHashCode;
+ break;
+ } else if (existing.equals(key)) {
+ throw new IllegalArgumentException("duplicate key: " + key);
+ }
+ }
+ }
+ keySetHashCode = keySetHashCodeMutable;
+ }
+
+ @Override public V get(Object key) {
+ if (key == null) {
+ return null;
+ }
+ for (int i = Hashing.smear(key.hashCode()); true; i++) {
+ int index = (i & mask) * 2;
+ Object candidate = table[index];
+ if (candidate == null) {
+ return null;
+ }
+ if (candidate.equals(key)) {
+ // we're careful to store only V's at odd indices
+ @SuppressWarnings("unchecked")
+ V value = (V) table[index + 1];
+ return value;
+ }
+ }
+ }
+
+ public int size() {
+ return entries.length;
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return get(key) != null;
+ }
+
+ @Override public boolean containsValue(Object value) {
+ if (value == null) {
+ return false;
+ }
+ for (Entry<K, V> entry : entries) {
+ if (entry.getValue().equals(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // TODO: Serialization of the map views should serialize the map, and
+ // deserialization should call entrySet(), keySet(), or values() on the
+ // deserialized map. The views are serializable since the Immutable* classes
+ // are.
+
+ private transient ImmutableSet<Entry<K, V>> entrySet;
+
+ @Override public ImmutableSet<Entry<K, V>> entrySet() {
+ ImmutableSet<Entry<K, V>> es = entrySet;
+ return (es == null) ? (entrySet = new EntrySet<K, V>(this)) : es;
+ }
+
+ private static class EntrySet<K, V> extends ArrayImmutableSet<Entry<K, V>> {
+ final RegularImmutableMap<K, V> map;
+
+ EntrySet(RegularImmutableMap<K, V> map) {
+ super(map.entries);
+ this.map = map;
+ }
+
+ @Override public boolean contains(Object target) {
+ if (target instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) target;
+ V mappedValue = map.get(entry.getKey());
+ return mappedValue != null && mappedValue.equals(entry.getValue());
+ }
+ return false;
+ }
+ }
+
+ private transient ImmutableSet<K> keySet;
+
+ @Override public ImmutableSet<K> keySet() {
+ ImmutableSet<K> ks = keySet;
+ return (ks == null) ? (keySet = new KeySet<K, V>(this)) : ks;
+ }
+
+ private static class KeySet<K, V>
+ extends TransformedImmutableSet<Map.Entry<K, V>, K> {
+ final RegularImmutableMap<K, V> map;
+
+ KeySet(RegularImmutableMap<K, V> map) {
+ super(map.entries, map.keySetHashCode);
+ this.map = map;
+ }
+
+ @Override K transform(Entry<K, V> element) {
+ return element.getKey();
+ }
+
+ @Override public boolean contains(Object target) {
+ return map.containsKey(target);
+ }
+ }
+
+ private transient ImmutableCollection<V> values;
+
+ @Override public ImmutableCollection<V> values() {
+ ImmutableCollection<V> v = values;
+ return (v == null) ? (values = new Values<V>(this)) : v;
+ }
+
+ private static class Values<V> extends ImmutableCollection<V> {
+ final RegularImmutableMap<?, V> map;
+
+ Values(RegularImmutableMap<?, V> map) {
+ this.map = map;
+ }
+
+ public int size() {
+ return map.entries.length;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ public Iterator<V> iterator() {
+ return new AbstractIterator<V>() {
+ int index = 0;
+ @Override protected V computeNext() {
+ return (index < map.entries.length)
+ ? map.entries[index++].getValue()
+ : endOfData();
+ }
+ };
+ }
+
+ @Override public boolean contains(Object target) {
+ return map.containsValue(target);
+ }
+ }
+
+ @Override public String toString() {
+ StringBuilder result = new StringBuilder(size() * 16)
+ .append('{')
+ .append(entries[0]);
+ for (int e = 1; e < entries.length; e++) {
+ result.append(", ").append(entries[e].toString());
+ }
+ return result.append('}').toString();
+ }
+ }
+
+ /*
+ * Serialized type for all ImmutableMap instances. It captures the logical
+ * contents and they are reconstructed using public factory methods. This
+ * ensures that the implementation types remain as implementation details.
+ */
+ private static class SerializedForm implements Serializable {
+ final Object[] keys;
+ final Object[] values;
+ SerializedForm(ImmutableMap<?, ?> map) {
+ keys = new Object[map.size()];
+ values = new Object[map.size()];
+ int i = 0;
+ for (Entry<?, ?> entry : map.entrySet()) {
+ keys[i] = entry.getKey();
+ values[i] = entry.getValue();
+ i++;
+ }
+ }
+ Object readResolve() {
+ Builder<Object, Object> builder = new Builder<Object, Object>();
+ for (int i = 0; i < keys.length; i++) {
+ builder.put(keys[i], values[i]);
+ }
+ return builder.build();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ Object writeReplace() {
+ return new SerializedForm(this);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,591 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An immutable {@link ListMultimap} with reliable user-specified key and value
+ * iteration order. Does not permit null keys or values.
+ *
+ * <p>Unlike {@link Multimaps#unmodifiableListMultimap(ListMultimap)}, which is
+ * a <i>view</i> of a separate map which can still change, an instance of
+ * {@code ImmutableMultimap} contains its own data and will <i>never</i> change.
+ * {@code ImmutableMultimap} is convenient for {@code public static final}
+ * multimaps ("constant multimaps") and also lets you easily make a "defensive
+ * copy" of a multimap provided to your class by a caller.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
+ * it has no public or protected constructors. Thus, instances of this class are
+ * guaranteed to be immutable.
+ *
+ * @author Jared Levy
+ */
+public class ImmutableMultimap<K, V>
+ implements ListMultimap<K, V>, Serializable {
+
+ private static ImmutableMultimap<Object, Object> EMPTY_MULTIMAP
+ = new EmptyMultimap();
+
+ private static class EmptyMultimap extends ImmutableMultimap<Object, Object> {
+ EmptyMultimap() {
+ super(ImmutableMap.<Object, ImmutableList<Object>>of(), 0);
+ }
+ @Override public boolean isEmpty() {
+ return true;
+ }
+ Object readResolve() {
+ return EMPTY_MULTIMAP; // preserve singleton property
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /** Returns the empty multimap. */
+ // Casting is safe because the multimap will never hold any elements.
+ @SuppressWarnings("unchecked")
+ public static <K, V> ImmutableMultimap<K, V> empty() {
+ return (ImmutableMultimap<K, V>) EMPTY_MULTIMAP;
+ }
+
+ /**
+ * Returns a new builder. The generated builder is equivalent to the builder
+ * created by the {@link Builder} constructor.
+ */
+ public static <K, V> Builder<K, V> builder() {
+ return new Builder<K, V>();
+ }
+
+ /**
+ * Multimap for {@link Builder} that maintains key and value orderings, allows
+ * duplicate values, and performs better than {@link LinkedListMultimap}.
+ */
+ private static class BuilderMultimap<K, V> extends StandardMultimap<K, V> {
+ BuilderMultimap() {
+ super(new LinkedHashMap<K, Collection<V>>());
+ }
+ @Override Collection<V> createCollection() {
+ return Lists.newArrayList();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * A builder for creating immutable multimap instances, especially
+ * {@code public static final} multimaps ("constant multimaps"). Example:
+ * <pre> {@code
+ *
+ * static final Multimap<String,Integer> STRING_TO_INTEGER_MULTIMAP =
+ * new ImmutableMultimap.Builder<String, Integer>()
+ * .put("one", 1)
+ * .putAll("several", 1, 2, 3)
+ * .putAll("many", 1, 2, 3, 4, 5)
+ * .build();}</pre>
+ *
+ * <p>Builder instances can be reused - it is safe to call {@link #build}
+ * multiple times to build multiple multimaps in series. Each multimap
+ * contains the key-value mappings in the previously created multimaps.
+ */
+ public static class Builder<K, V> {
+ private final Multimap<K, V> builderMultimap = new BuilderMultimap<K, V>();
+
+ /**
+ * Creates a new builder. The returned builder is equivalent to the builder
+ * generated by {@link ImmutableMultimap#builder}.
+ */
+ public Builder() {}
+
+ /**
+ * Adds a key-value mapping to the built multimap.
+ */
+ public Builder<K, V> put(K key, V value) {
+ builderMultimap.put(checkNotNull(key), checkNotNull(value));
+ return this;
+ }
+
+ /**
+ * Stores a collection of values with the same key in the built multimap.
+ *
+ * @throws NullPointerException if {@code key}, {@code values}, or any
+ * element in {@code values} is null. The builder is left in an invalid
+ * state.
+ */
+ public Builder<K, V> putAll(K key, Iterable<? extends V> values) {
+ Collection<V> valueList = builderMultimap.get(checkNotNull(key));
+ for (V value : values) {
+ valueList.add(checkNotNull(value));
+ }
+ return this;
+ }
+
+ /**
+ * Stores an array of values with the same key in the built multimap.
+ *
+ * @throws NullPointerException if the key or any value is null. If a later
+ * value is null, earlier values may be added to the builder.
+ */
+ public Builder<K, V> putAll(K key, V... values) {
+ Collection<V> valueList = builderMultimap.get(checkNotNull(key));
+ for (V value : values) {
+ valueList.add(checkNotNull(value));
+ }
+ return this;
+ }
+
+ public ImmutableMultimap<K, V> build() {
+ return copyOf(builderMultimap);
+ }
+ }
+
+ /**
+ * Returns an immutable multimap containing the same mappings as
+ * {@code multimap}. The generated multimap's key and value orderings
+ * correspond to the iteration ordering of the {@code multimap.asMap()} view.
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if
+ * {@code multimap} is an {@code ImmutableMultimap}, no copy will actually be
+ * performed, and the given map itself will be returned.
+ *
+ * @throws NullPointerException if any key or value in {@code multimap} is
+ * null
+ */
+ public static <K, V> ImmutableMultimap<K, V> copyOf(
+ Multimap<? extends K, ? extends V> multimap) {
+ if (multimap.isEmpty()) {
+ return empty();
+ }
+
+ if (multimap instanceof ImmutableMultimap) {
+ @SuppressWarnings("unchecked") // safe since multimap is not writable
+ ImmutableMultimap<K, V> kvMultimap = (ImmutableMultimap<K, V>) multimap;
+ return kvMultimap;
+ }
+
+ ImmutableMap.Builder<K, ImmutableList<V>> builder = ImmutableMap.builder();
+ int size = 0;
+
+ for (Map.Entry<? extends K, ? extends Collection<? extends V>> entry
+ : multimap.asMap().entrySet()) {
+ ImmutableList<V> list = ImmutableList.copyOf(entry.getValue());
+ if (!list.isEmpty()) {
+ builder.put(entry.getKey(), list);
+ size += list.size();
+ }
+ }
+
+ return new ImmutableMultimap<K, V>(builder.build(), size);
+ }
+
+ private final transient ImmutableMap<K, ImmutableList<V>> map;
+ private final transient int size;
+
+ private ImmutableMultimap(ImmutableMap<K, ImmutableList<V>> map, int size) {
+ this.map = map;
+ this.size = size;
+ }
+
+ // mutators (not supported)
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public List<V> removeAll(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public List<V> replaceValues(K key, Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public boolean put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public boolean putAll(K key, Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the multimap unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public boolean remove(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ // accessors
+
+ public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
+ Collection<V> valueList = map.get(key);
+ return (valueList != null) && valueList.contains(value);
+ }
+
+ public boolean containsKey(@Nullable Object key) {
+ return map.containsKey(key);
+ }
+
+ public boolean containsValue(@Nullable Object value) {
+ for (Collection<V> valueList : map.values()) {
+ if (valueList.contains(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj instanceof Multimap) {
+ Multimap<?, ?> that = (Multimap<?, ?>) obj;
+ return map.equals(that.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ return map.toString();
+ }
+
+ // views
+
+ /**
+ * Returns an immutable list of the values for the given key. If no mappings
+ * in the multimap have the provided key, an empty immutable list is returned.
+ * The values are in the same order as the parameters used to build this
+ * multimap.
+ */
+ public ImmutableList<V> get(@Nullable K key) {
+ ImmutableList<V> list = map.get(key);
+ return (list == null) ? ImmutableList.<V>of() : list;
+ }
+
+ /**
+ * Returns an immutable set of the distinct keys in this multimap. These keys
+ * are ordered according to when they first appeared during the construction
+ * of this multimap.
+ */
+ public ImmutableSet<K> keySet() {
+ return map.keySet();
+ }
+
+ /**
+ * Returns an immutable map that associates each key with its corresponding
+ * values in the multimap. Though the method signature doesn't say so
+ * explicitly, the returned map has {@link ImmutableList} values.
+ */
+ @SuppressWarnings("unchecked") // a widening cast
+ public ImmutableMap<K, Collection<V>> asMap() {
+ return (ImmutableMap) map;
+ }
+
+ private transient ImmutableCollection<Map.Entry<K, V>> entries;
+
+ /**
+ * Returns an immutable collection of all key-value pairs in the multimap. Its
+ * iterator traverses the values for the first key, the values for the second
+ * key, and so on.
+ */
+ public ImmutableCollection<Map.Entry<K, V>> entries() {
+ ImmutableCollection<Map.Entry<K, V>> result = entries;
+ return (result == null) ? (entries = new Entries<K, V>(this)) : result;
+ }
+
+ private static class Entries<K, V>
+ extends ImmutableCollection<Map.Entry<K, V>> {
+ final ImmutableMultimap<K, V> multimap;
+
+ Entries(ImmutableMultimap<K, V> multimap) {
+ this.multimap = multimap;
+ }
+
+ public Iterator<Map.Entry<K, V>> iterator() {
+ final Iterator<Map.Entry<K, ImmutableList<V>>> mapIterator
+ = multimap.map.entrySet().iterator();
+
+ return new UnmodifiableIterator<Map.Entry<K, V>>() {
+ Map.Entry<K, ImmutableList<V>> mapEntry;
+ int index;
+
+ public boolean hasNext() {
+ return ((mapEntry != null) && (index < mapEntry.getValue().size()))
+ || mapIterator.hasNext();
+ }
+
+ public Map.Entry<K, V> next() {
+ if ((mapEntry == null) || (index >= mapEntry.getValue().size())) {
+ mapEntry = mapIterator.next();
+ index = 0;
+ }
+ V value = mapEntry.getValue().get(index);
+ index++;
+ return Maps.immutableEntry(mapEntry.getKey(), value);
+ }
+ };
+ }
+
+ public int size() {
+ return multimap.size();
+ }
+
+ @Override public boolean contains(Object object) {
+ if (object instanceof Map.Entry) {
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+ return multimap.containsEntry(entry.getKey(), entry.getValue());
+ }
+ return false;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private transient ImmutableMultiset<K> keys;
+
+ /**
+ * Returns a collection, which may contain duplicates, of all keys. The number
+ * of times of key appears in the returned multiset equals the number of
+ * mappings the key has in the multimap. Duplicate keys appear consecutively
+ * in the multiset's iteration order.
+ */
+ public ImmutableMultiset<K> keys() {
+ ImmutableMultiset<K> result = keys;
+ return (result == null)
+ ? (keys = new ImmutableMultiset<K>(new CountMap<K, V>(this), size))
+ : result;
+ }
+
+ /**
+ * Map from key to value count, used to create the {@link #keys} multiset.
+ * Methods that {@link ImmutableMultiset} doesn't require are unsupported.
+ */
+ private static class CountMap<K, V> extends ImmutableMap<K, Integer> {
+ final ImmutableMultimap<K, V> multimap;
+
+ CountMap(ImmutableMultimap<K, V> multimap) {
+ this.multimap = multimap;
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return multimap.containsKey(key);
+ }
+
+ @Override public boolean containsValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public Integer get(Object key) {
+ Collection<?> valueList = multimap.map.get(key);
+ return (valueList == null) ? 0 : valueList.size();
+ }
+
+ @Override public ImmutableSet<K> keySet() {
+ return multimap.keySet();
+ }
+
+ @Override public ImmutableCollection<Integer> values() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isEmpty() {
+ return multimap.isEmpty();
+ }
+
+ public int size() {
+ return multimap.map.size();
+ }
+
+ transient ImmutableSet<Entry<K, Integer>> entrySet;
+
+ @Override public ImmutableSet<Entry<K, Integer>> entrySet() {
+ ImmutableSet<Entry<K, Integer>> result = entrySet;
+ return (result == null)
+ ? entrySet = new EntrySet<K, V>(multimap) : result;
+ }
+
+ private static class EntrySet<K, V>
+ extends ImmutableSet<Entry<K, Integer>> {
+ final ImmutableMultimap<K, V> multimap;
+
+ EntrySet(ImmutableMultimap<K, V> multimap) {
+ this.multimap = multimap;
+ }
+
+ public Iterator<Entry<K, Integer>> iterator() {
+ final Iterator<Entry<K, ImmutableList<V>>> mapIterator
+ = multimap.map.entrySet().iterator();
+ return new UnmodifiableIterator<Entry<K, Integer>>() {
+ public boolean hasNext() {
+ return mapIterator.hasNext();
+ }
+ public Entry<K, Integer> next() {
+ Entry<K, ImmutableList<V>> entry = mapIterator.next();
+ return Maps.immutableEntry(entry.getKey(), entry.getValue().size());
+ }
+ };
+ }
+
+ public int size() {
+ return multimap.map.size();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private transient ImmutableCollection<V> values;
+
+ /**
+ * Returns an immutable collection of the values in this multimap. Its
+ * iterator traverses the values for the first key, the values for the second
+ * key, and so on.
+ */
+ public ImmutableCollection<V> values() {
+ ImmutableCollection<V> v = values;
+ return (v == null) ? (values = new Values<V>(this)) : v;
+ }
+
+ private static class Values<V> extends ImmutableCollection<V> {
+ final Multimap<?, V> multimap;
+
+ Values(Multimap<?, V> multimap) {
+ this.multimap = multimap;
+ }
+
+ public Iterator<V> iterator() {
+ final Iterator<? extends Map.Entry<?, V>> entryIterator
+ = multimap.entries().iterator();
+ return new UnmodifiableIterator<V>() {
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ public V next() {
+ return entryIterator.next().getValue();
+ }
+ };
+ }
+
+ public int size() {
+ return multimap.size();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * @serialData number of distinct keys, and then for each distinct key: the
+ * key, the number of values for that key, and the key's values
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMultimap(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException, NoSuchFieldException {
+ stream.defaultReadObject();
+ int keyCount = stream.readInt();
+ if (keyCount < 0) {
+ throw new InvalidObjectException("Invalid key count " + keyCount);
+ }
+ ImmutableMap.Builder<K, ImmutableList<V>> builder = ImmutableMap.builder();
+ int tmpSize = 0;
+
+ for (int i = 0; i < keyCount; i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMultimap
+ K key = (K) stream.readObject();
+ int valueCount = stream.readInt();
+ if (valueCount <= 0) {
+ throw new InvalidObjectException("Invalid value count " + valueCount);
+ }
+ @SuppressWarnings("unchecked") // casting a newly allocated array
+ V[] values = (V[]) new Object[valueCount];
+ for (int j = 0; j < valueCount; j++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMultimap
+ V value = (V) stream.readObject();
+ values[j] = value;
+ tmpSize += valueCount;
+ }
+ builder.put(key, ImmutableList.of(values));
+ }
+
+ Serialization.setFinalField(
+ ImmutableMultimap.class, this, "map", builder.build());
+ Serialization.setFinalField(ImmutableMultimap.class, this, "size", tmpSize);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An immutable hash-based multiset. Does not permit null elements.
+ *
+ * <p>Its iterator orders elements according to the first appearance of the
+ * element among the items passed to the factory method. When the multiset
+ * contains multiple instances of an element, those instances are consecutive in
+ * the iteration order.
+ *
+ * @author Jared Levy
+ */
+public class ImmutableMultiset<E> extends ImmutableCollection<E>
+ implements Multiset<E> {
+
+ private static final ImmutableMultiset<Object> EMPTY_MULTISET
+ = new EmptyMultiset();
+
+ private static class EmptyMultiset extends ImmutableMultiset<Object> {
+ EmptyMultiset() {
+ super(ImmutableMap.<Object, Integer>of(), 0);
+ }
+ Object readResolve() {
+ return EMPTY_MULTISET; // preserve singleton property
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns the empty immutable multiset.
+ */
+ @SuppressWarnings("unchecked") // all supported methods are covariant
+ public static <E> ImmutableMultiset<E> of() {
+ return (ImmutableMultiset<E>) EMPTY_MULTISET;
+ }
+
+ /**
+ * Returns an immutable multiset containing the given elements.
+ *
+ * <p>The multiset is ordered by the first occurrence of each element. For
+ * example, {@code ImmutableMultiset.of(2, 3, 1, 3)} yields a multiset with
+ * elements in the order {@code 2, 3, 3, 1}.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableMultiset<E> of(E... elements) {
+ return copyOf(Arrays.asList(elements));
+ }
+
+ /**
+ * Returns an immutable multiset containing the given elements.
+ *
+ * <p>The multiset is ordered by the first occurrence of each element. For
+ * example, {@code ImmutableMultiset.copyOf(Arrays.asList(2, 3, 1, 3))} yields
+ * a multiset with elements in the order {@code 2, 3, 3, 1}.
+ *
+ * <p>Note that if {@code c} is a {@code Collection<String>}, then {@code
+ * ImmutableMultiset.copyOf(c)} returns an {@code ImmutableMultiset<String>}
+ * containing each of the strings in {@code c}, while
+ * {@code ImmutableMultiset.of(c)} returns an
+ * {@code ImmutableMultiset<Collection<String>>} containing one element (the
+ * given collection itself).
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
+ * is an {@code ImmutableMultiset}, no copy will actually be performed, and
+ * the given multiset itself will be returned.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableMultiset<E> copyOf(
+ Iterable<? extends E> elements) {
+ if (elements instanceof ImmutableMultiset) {
+ @SuppressWarnings("unchecked") // all supported methods are covariant
+ ImmutableMultiset<E> result = (ImmutableMultiset<E>) elements;
+ return result;
+ }
+
+ @SuppressWarnings("unchecked") // the cast causes a warning
+ Multiset<? extends E> multiset = (elements instanceof Multiset)
+ ? (Multiset<? extends E>) elements
+ : new LinkedHashMultiset<E>(elements);
+
+ return copyOfInternal(multiset);
+ }
+
+
+ private static <E> ImmutableMultiset<E> copyOfInternal(
+ Multiset<? extends E> multiset) {
+ long size = 0;
+ ImmutableMap.Builder<E, Integer> builder = ImmutableMap.builder();
+
+ for (Entry<? extends E> entry : multiset.entrySet()) {
+ int count = entry.getCount();
+ if (count > 0) {
+ // Since ImmutableMap.Builder throws an NPE if an element is null, no
+ // other null checks are needed.
+ builder.put(entry.getElement(), count);
+ size += count;
+ }
+ }
+
+ return new ImmutableMultiset<E>(
+ builder.build(), (int) Math.min(size, Integer.MAX_VALUE));
+ }
+
+ /**
+ * Returns an immutable multiset containing the given elements.
+ *
+ * <p>The multiset is ordered by the first occurrence of each element. For
+ * example,
+ * {@code ImmutableMultiset.copyOf(Arrays.asList(2, 3, 1, 3).iterator())}
+ * yields a multiset with elements in the order {@code 2, 3, 3, 1}.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableMultiset<E> copyOf(
+ Iterator<? extends E> elements) {
+ Multiset<E> multiset = new LinkedHashMultiset<E>();
+ Iterators.addAll(multiset, elements);
+ return copyOfInternal(multiset);
+ }
+
+ private final transient ImmutableMap<E, Integer> map;
+ private final transient int size;
+
+ ImmutableMultiset(ImmutableMap<E, Integer> map, int size) {
+ this.map = map;
+ this.size = size;
+ }
+
+ public int count(@Nullable Object element) {
+ Integer value = map.get(element);
+ return (value == null) ? 0 : value;
+ }
+
+ public Iterator<E> iterator() {
+ final Iterator<Map.Entry<E, Integer>> mapIterator
+ = map.entrySet().iterator();
+
+ return new Iterator<E>() {
+ int remaining;
+ E element;
+
+ public boolean hasNext() {
+ return (remaining > 0) || mapIterator.hasNext();
+ }
+
+ public E next() {
+ if (remaining <= 0) {
+ Map.Entry<E, Integer> entry = mapIterator.next();
+ element = entry.getKey();
+ remaining = entry.getValue();
+ }
+ remaining--;
+ return element;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public int size() {
+ return size;
+ }
+
+ @Override public boolean contains(@Nullable Object element) {
+ return map.containsKey(element);
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public boolean add(E element, int occurrences) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public int remove(Object element, int occurrences) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Guaranteed to throw an exception and leave the collection unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public int removeAllOccurrences(Object element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean equals(@Nullable Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (other instanceof Multiset) {
+ Multiset<?> that = (Multiset<?>) other;
+ if (this.size() != that.size()) {
+ return false;
+ }
+ for (Entry<?> entry : that.entrySet()) {
+ if (count(entry.getElement()) != entry.getCount()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override public int hashCode() {
+ // could cache this, but not considered worthwhile to do so
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ return entrySet().toString();
+ }
+
+ // TODO: Serialization of the element set should serialize the multiset, and
+ // deserialization should call multiset.elementSet(). Then
+ // reserialized(multiset).elementSet() == reserialized(multiset.elementSet())
+ // Currently, those object references differ.
+ public Set<E> elementSet() {
+ return map.keySet();
+ }
+
+ private transient ImmutableSet<Entry<E>> entrySet;
+
+ public Set<Entry<E>> entrySet() {
+ ImmutableSet<Entry<E>> es = entrySet;
+ return (es == null) ? (entrySet = new EntrySet<E>(this)) : es;
+ }
+
+ private static class EntrySet<E> extends ImmutableSet<Entry<E>> {
+ final ImmutableMultiset<E> multiset;
+
+ public EntrySet(ImmutableMultiset<E> multiset) {
+ this.multiset = multiset;
+ }
+
+ public Iterator<Entry<E>> iterator() {
+ final Iterator<Map.Entry<E, Integer>> mapIterator
+ = multiset.map.entrySet().iterator();
+ return new Iterator<Entry<E>>() {
+ public boolean hasNext() {
+ return mapIterator.hasNext();
+ }
+ public Entry<E> next() {
+ Map.Entry<E, Integer> mapEntry = mapIterator.next();
+ return
+ Multisets.immutableEntry(mapEntry.getKey(), mapEntry.getValue());
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public int size() {
+ return multiset.map.size();
+ }
+
+ @Override public boolean contains(Object o) {
+ if (o instanceof Entry) {
+ Entry<?> entry = (Entry<?>) o;
+ if (entry.getCount() <= 0) {
+ return false;
+ }
+ int count = multiset.count(entry.getElement());
+ return count == entry.getCount();
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return multiset.map.hashCode();
+ }
+
+ @Override Object writeReplace() {
+ return this;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * @serialData the number of distinct elements, the first element, its count,
+ * the second element, its count, and so on
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMultiset(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException, NoSuchFieldException {
+ stream.defaultReadObject();
+ int entryCount = stream.readInt();
+ ImmutableMap.Builder<E, Integer> builder = ImmutableMap.builder();
+ long tmpSize = 0;
+ for (int i = 0; i < entryCount; i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMultiset
+ E element = (E) stream.readObject();
+ int count = stream.readInt();
+ if (count <= 0) {
+ throw new InvalidObjectException("Invalid count " + count);
+ }
+ builder.put(element, count);
+ tmpSize += count;
+ }
+
+ Serialization.setFinalField(ImmutableMultiset.class, this, "map",
+ builder.build());
+ Serialization.setFinalField(ImmutableMultiset.class, this, "size",
+ (int) Math.min(tmpSize, Integer.MAX_VALUE));
+ }
+
+ @Override Object writeReplace() {
+ return this;
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSet.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSet.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSet.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A high-performance, immutable {@code Set} with reliable, user-specified
+ * iteration order. Does not permit null elements.
+ *
+ * <p>Unlike {@link Collections#unmodifiableSet}, which is a <i>view</i> of a
+ * separate collection that can still change, an instance of this class contains
+ * its own private data and will <i>never</i> change. This class is convenient
+ * for {@code public static final} sets ("constant sets") and also lets you
+ * easily make a "defensive copy" of a set provided to your class by a caller.
+ *
+ * <p><b>Warning:</b> Like most sets, an {@code ImmutableSet} will not function
+ * correctly if an element is modified after being placed in the set. For this
+ * reason, and to avoid general confusion, it is strongly recommended to place
+ * only immutable objects into this collection.
+ *
+ * <p>This class has been observed to perform significantly better than {@link
+ * HashSet} for objects with very fast {@link Object#hashCode} implementations
+ * (as a well-behaved immutable object should). While this class's factory
+ * methods create hash-based instances, the {@link ImmutableSortedSet} subclass
+ * performs binary searches instead.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed
+ * outside its package as it has no public or protected constructors. Thus,
+ * instances of this type are guaranteed to be immutable.
+ *
+ * @see ImmutableList
+ * @see ImmutableMap
+ * @author Kevin Bourrillion
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public abstract class ImmutableSet<E> extends ImmutableCollection<E>
+ implements Set<E> {
+ private static final ImmutableSet<?> EMPTY_IMMUTABLE_SET
+ = new EmptyImmutableSet();
+
+ /**
+ * Returns the empty immutable set. This set behaves and performs comparably
+ * to {@link Collections#emptySet}, and is preferable mainly for consistency
+ * and maintainability of your code.
+ */
+ // Casting to any type is safe because the set will never hold any elements.
+ @SuppressWarnings({"unchecked"})
+ public static <E> ImmutableSet<E> of() {
+ return (ImmutableSet<E>) EMPTY_IMMUTABLE_SET;
+ }
+
+ /**
+ * Returns an immutable set containing a single element. This set behaves and
+ * performs comparably to {@link Collections#singleton}, but will not accept
+ * a null element. It is preferable mainly for consistency and
+ * maintainability of your code.
+ */
+ public static <E> ImmutableSet<E> of(E element) {
+ return new SingletonImmutableSet<E>(element, element.hashCode());
+ }
+
+ /**
+ * Returns an immutable set containing the given elements, in order. Repeated
+ * occurrences of an element (according to {@link Object#equals}) after the
+ * first are ignored (but too many of these may result in the set being
+ * sized inappropriately).
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableSet<E> of(E... elements) {
+ switch (elements.length) {
+ case 0:
+ return of();
+ case 1:
+ return of(elements[0]);
+ default:
+ return create(Arrays.asList(elements), elements.length);
+ }
+ }
+
+ /**
+ * Returns an immutable set containing the given elements, in order. Repeated
+ * occurrences of an element (according to {@link Object#equals}) after the
+ * first are ignored (but too many of these may result in the set being
+ * sized inappropriately).
+ *
+ * <p>Note that if {@code s} is a {@code Set<String>}, then {@code
+ * ImmutableSet.copyOf(s)} returns an {@code ImmutableSet<String>} containing
+ * each of the strings in {@code s}, while {@code ImmutableSet.of(s)} returns
+ * a {@code ImmutableSet<Set<String>>} containing one element (the given set
+ * itself).
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
+ * is an {@code ImmutableSet}, no copy will actually be performed, and the
+ * given set itself will be returned.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableSet<E> copyOf(Iterable<? extends E> elements) {
+ if (elements instanceof ImmutableSet) {
+ @SuppressWarnings("unchecked") // all supported methods are covariant
+ ImmutableSet<E> set = (ImmutableSet<E>) elements;
+ return set;
+ }
+ return copyOfInternal(Collections2.toCollection(elements));
+ }
+
+ /**
+ * Returns an immutable set containing the given elements, in order. Repeated
+ * occurrences of an element (according to {@link Object#equals}) after the
+ * first are ignored.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public static <E> ImmutableSet<E> copyOf(Iterator<? extends E> elements) {
+ Collection<E> list = Lists.newArrayList(elements);
+ return copyOfInternal(list);
+ }
+
+ private static <E> ImmutableSet<E> copyOfInternal(
+ Collection<? extends E> collection) {
+ // TODO: Support concurrent collections that change while this method is
+ // running.
+ switch (collection.size()) {
+ case 0:
+ return of();
+ case 1:
+ // TODO: Remove "ImmutableSet.<E>" when eclipse bug is fixed.
+ return ImmutableSet.<E>of(collection.iterator().next());
+ default:
+ return create(collection, collection.size());
+ }
+ }
+
+ ImmutableSet() {}
+
+ /** Returns {@code true} if the {@code hashCode()} method runs quickly. */
+ boolean isHashCodeFast() {
+ return false;
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof ImmutableSet
+ && isHashCodeFast()
+ && ((ImmutableSet<?>) object).isHashCodeFast()
+ && hashCode() != object.hashCode()) {
+ return false;
+ }
+ if (object instanceof Set) {
+ Set<?> that = (Set<?>) object;
+ return size() == that.size() && containsAll(that);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return Sets.hashCodeImpl(this);
+ }
+
+ @Override public String toString() {
+ if (isEmpty()) {
+ return "[]";
+ }
+ Iterator<E> iterator = iterator();
+ StringBuilder result = new StringBuilder(size() * 16);
+ result.append('[').append(iterator.next().toString());
+ for (int i = 1; i < size(); i++) {
+ result.append(", ").append(iterator.next().toString());
+ }
+ return result.append(']').toString();
+ }
+
+ private static final class EmptyImmutableSet extends ImmutableSet<Object> {
+ public int size() {
+ return 0;
+ }
+
+ @Override public boolean isEmpty() {
+ return true;
+ }
+
+ @Override public boolean contains(Object target) {
+ return false;
+ }
+
+ public Iterator<Object> iterator() {
+ return Iterators.emptyIterator();
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.EMPTY_ARRAY;
+ }
+
+ @Override public <T> T[] toArray(T[] a) {
+ if (a.length > 0) {
+ a[0] = null;
+ }
+ return a;
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ return targets.isEmpty();
+ }
+
+ @Override public boolean equals(Object object) {
+ return object == this
+ || (object instanceof Set && ((Set<?>) object).isEmpty());
+ }
+
+ @Override public final int hashCode() {
+ return 0;
+ }
+
+ @Override boolean isHashCodeFast() {
+ return true;
+ }
+
+ @Override public String toString() {
+ return "[]";
+ }
+ }
+
+ private static final class SingletonImmutableSet<E> extends ImmutableSet<E> {
+ final E element;
+ final int hashCode;
+
+ SingletonImmutableSet(E element, int hashCode) {
+ this.element = element;
+ this.hashCode = hashCode;
+ }
+
+ public int size() {
+ return 1;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public boolean contains(Object target) {
+ return element.equals(target);
+ }
+
+ public Iterator<E> iterator() {
+ return Iterators.singletonIterator(element);
+ }
+
+ @Override public Object[] toArray() {
+ return new Object[] { element };
+ }
+
+ @SuppressWarnings({"unchecked"})
+ @Override public <T> T[] toArray(T[] array) {
+ if (array.length == 0) {
+ array = ObjectArrays.newArray(array, 1);
+ } else if (array.length > 1) {
+ array[1] = null;
+ }
+ array[0] = (T) element;
+ return array;
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Set) {
+ Set<?> set = (Set<?>) object;
+ return set.size() == 1 && contains(set.iterator().next());
+ }
+ return false;
+ }
+
+ @Override public final int hashCode() {
+ return hashCode;
+ }
+
+ @Override boolean isHashCodeFast() {
+ return true;
+ }
+
+ @Override public String toString() {
+ String elementToString = element.toString();
+ return new StringBuilder(elementToString.length() + 2)
+ .append('[')
+ .append(elementToString)
+ .append(']')
+ .toString();
+ }
+ }
+
+ private static <E> ImmutableSet<E> create(
+ Iterable<? extends E> iterable, int count) {
+ // count is always the (nonzero) number of elements in the iterable
+ int tableSize = Hashing.chooseTableSize(count);
+ Object[] table = new Object[tableSize];
+ int mask = tableSize - 1;
+
+ List<E> elements = new ArrayList<E>(count);
+ int hashCode = 0;
+
+ for (E element : iterable) {
+ int hash = element.hashCode();
+ for (int i = Hashing.smear(hash); true; i++) {
+ int index = i & mask;
+ Object value = table[index];
+ if (value == null) {
+ // Came to an empty bucket. Put the element here.
+ table[index] = element;
+ elements.add(element);
+ hashCode += hash;
+ break;
+ } else if (value.equals(element)) {
+ break; // Found a duplicate. Nothing to do.
+ }
+ }
+ }
+
+ // The iterable might have contained only duplicates of the same element.
+ return (elements.size() == 1)
+ ? new SingletonImmutableSet<E>(elements.get(0), hashCode)
+ : new RegularImmutableSet<E>(elements.toArray(), hashCode, table, mask);
+ }
+
+ abstract static class ArrayImmutableSet<E> extends ImmutableSet<E> {
+ final Object[] elements; // the elements (two or more) in the desired order
+
+ ArrayImmutableSet(Object[] elements) {
+ this.elements = elements;
+ }
+
+ public int size() {
+ return elements.length;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ /*
+ * The cast is safe because the only way to create an instance is via the
+ * create() method above, which only permits elements of type E.
+ */
+ @SuppressWarnings("unchecked")
+ public Iterator<E> iterator() {
+ return (Iterator<E>) Iterators.forArray(elements);
+ }
+
+ @Override public Object[] toArray() {
+ Object[] array = new Object[size()];
+ System.arraycopy(elements, 0, array, 0, size());
+ return array;
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ int size = size();
+ if (array.length < size) {
+ array = ObjectArrays.newArray(array, size);
+ } else if (array.length > size) {
+ array[size] = null;
+ }
+ System.arraycopy(elements, 0, array, 0, size);
+ return array;
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ if (targets == this) {
+ return true;
+ }
+ if (!(targets instanceof ArrayImmutableSet)) {
+ return super.containsAll(targets);
+ }
+ if (targets.size() > size()) {
+ return false;
+ }
+ for (Object target : ((ArrayImmutableSet<?>) targets).elements) {
+ if (!contains(target)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private static final class RegularImmutableSet<E>
+ extends ArrayImmutableSet<E> {
+ final Object[] table; // the same elements in hashed positions (plus nulls)
+ final int mask; // 'and' with an int to get a valid table index
+ final int hashCode;
+
+ RegularImmutableSet(Object[] elements, int hashCode,
+ Object[] table, int mask) {
+ super(elements);
+ this.table = table;
+ this.mask = mask;
+ this.hashCode = hashCode;
+ }
+
+ @Override public boolean contains(Object target) {
+ if (target == null) {
+ return false;
+ }
+ for (int i = Hashing.smear(target.hashCode()); true; i++) {
+ Object candidate = table[i & mask];
+ if (candidate == null) {
+ return false;
+ }
+ if (candidate.equals(target)) {
+ return true;
+ }
+ }
+ }
+
+ @Override public int hashCode() {
+ return hashCode;
+ }
+
+ @Override boolean isHashCodeFast() {
+ return true;
+ }
+ }
+
+ /** such as ImmutableMap.keySet() */
+ abstract static class TransformedImmutableSet<D, E> extends ImmutableSet<E> {
+ final D[] source;
+ final int hashCode;
+
+ TransformedImmutableSet(D[] source, int hashCode) {
+ this.source = source;
+ this.hashCode = hashCode;
+ }
+
+ abstract E transform(D element);
+
+ public int size() {
+ return source.length;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ public Iterator<E> iterator() {
+ return new AbstractIterator<E>() {
+ int index = 0;
+ @Override protected E computeNext() {
+ return index < source.length
+ ? transform(source[index++])
+ : endOfData();
+ }
+ };
+ }
+
+ @Override public Object[] toArray() {
+ return toArray(new Object[size()]);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override public <T> T[] toArray(T[] array) {
+ int size = size();
+ if (array.length < size) {
+ array = ObjectArrays.newArray(array, size);
+ } else if (array.length > size) {
+ array[size] = null;
+ }
+
+ for (int i = 0; i < source.length; i++) {
+ array[i] = (T) transform(source[i]);
+ }
+ return array;
+ }
+
+ @Override public final int hashCode() {
+ return hashCode;
+ }
+
+ @Override boolean isHashCodeFast() {
+ return true;
+ }
+ }
+
+ /*
+ * This class is used to serialize all ImmutableSet instances, regardless of
+ * implementation type. It captures their "logical contents" and they are
+ * reconstructed using public static factories. This is necessary to ensure
+ * that the existence of a particular implementation type is an implementation
+ * detail.
+ */
+ private static class SerializedForm implements Serializable {
+ final Object[] elements;
+ SerializedForm(Object[] elements) {
+ this.elements = elements;
+ }
+ Object readResolve() {
+ return of(elements);
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ @Override Object writeReplace() {
+ return new SerializedForm(toArray());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSortedSet.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSortedSet.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ImmutableSortedSet.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,832 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import org.richfaces.collections.base.Objects;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * An immutable {@code SortedSet} that stores its elements in a sorted array.
+ * Some instances are ordered by an explicit comparator, while others follow the
+ * natural sort ordering of their elements. Either way, null elements are not
+ * supported.
+ *
+ * <p>Unlike {@link Collections#unmodifiableSortedSet}, which is a <i>view</i>
+ * of a separate collection that can still change, an instance of {@code
+ * ImmutableSortedSet} contains its own private data and will <i>never</i>
+ * change. This class is convenient for {@code public static final} sets
+ * ("constant sets") and also lets you easily make a "defensive copy" of a set
+ * provided to your class by a caller.
+ *
+ * <p>The sets returned by {@link #headSet}, {@link #tailSet}, and
+ * {@link #subSet} methods share the same array as the original set, preventing
+ * that array from being garbage collected. If this is a concern, the data may
+ * be copied into a correctly-sized array by calling {@link #copyOfSorted}.
+ *
+ * <p><b>Note on element equivalence:</b> The {@link #contains(Object)},
+ * {@link #containsAll(Collection)}, and {@link #equals(Object)}
+ * implementations must check whether a provided object is equivalent to an
+ * element in the collection. Unlike most collections, an
+ * {@code ImmutableSortedSet} doesn't use {@link Object#equals} to determine if
+ * two elements are equivalent. Instead, with an explicit comparator, the
+ * following relation determines whether elements {@code x} and {@code y} are
+ * equivalent: <pre> {@code
+ *
+ * {(x, y) | comparator.compare(x, y) == 0}}</pre>
+ *
+ * With natural ordering of elements, the following relation determines whether
+ * two elements are equivalent: <pre> {@code
+ *
+ * {(x, y) | x.compareTo(y) == 0}}</pre>
+ *
+ * <b>Warning:</b> Like most sets, an {@code ImmutableSortedSet} will not
+ * function correctly if an element is modified after being placed in the set.
+ * For this reason, and to avoid general confusion, it is strongly recommended
+ * to place only immutable objects into this collection.
+ *
+ * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
+ * it has no public or protected constructors. Thus, instances of this type are
+ * guaranteed to be immutable.
+ *
+ * @see ImmutableSet
+ * @author Jared Levy
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public abstract class ImmutableSortedSet<E> extends ImmutableSet<E>
+ implements SortedSet<E> {
+
+ // TODO: Can we find a way to remove these @SuppressWarnings?
+ @SuppressWarnings("unchecked")
+ private static final Comparator NATURAL_ORDER = Comparators.naturalOrder();
+ @SuppressWarnings("unchecked")
+ private static final ImmutableSortedSet<Object> NATURAL_EMPTY_SET =
+ new EmptyImmutableSortedSet<Object>(NATURAL_ORDER);
+
+ @SuppressWarnings("unchecked")
+ private static <E> ImmutableSortedSet<E> emptySet() {
+ return (ImmutableSortedSet<E>) NATURAL_EMPTY_SET;
+ }
+
+ private static <E> ImmutableSortedSet<E> emptySet(
+ Comparator<? super E> comparator) {
+ if (comparator == NATURAL_ORDER) {
+ return emptySet();
+ } else {
+ return new EmptyImmutableSortedSet<E>(comparator);
+ }
+ }
+
+ /**
+ * Returns the empty immutable sorted set.
+ */
+ public static <E> ImmutableSortedSet<E> of() {
+ return emptySet();
+ }
+
+ /**
+ * Returns an immutable sorted set containing a single element.
+ *
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
+ */
+ @SuppressWarnings("unchecked") // See method Javadoc
+ public static <E extends Comparable> ImmutableSortedSet<E> of(E element) {
+ Object[] array = { checkNotNull(element) };
+ return new RegularImmutableSortedSet<E>(array, NATURAL_ORDER);
+ }
+
+ // TODO: Consider adding factory methods that throw an exception when given
+ // duplicate elements.
+
+ /**
+ * Returns an immutable sorted set containing the given elements sorted by
+ * their natural ordering. When multiple elements are equivalent according to
+ * {@link Comparable#compareTo}, only the first one specified is included.
+ *
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ @SuppressWarnings("unchecked") // See method Javadoc
+ public static <E extends Comparable> ImmutableSortedSet<E> of(E... elements) {
+ return ofInternal(Comparators.naturalOrder(), elements);
+ }
+
+ private static <E> ImmutableSortedSet<E> ofInternal(
+ Comparator<? super E> comparator, E... elements) {
+ switch (elements.length) {
+ case 0:
+ return emptySet(comparator);
+ default:
+ Object[] array = elements.clone();
+ for (Object element : array) {
+ checkNotNull(element);
+ }
+ sort(array, comparator);
+ array = removeDupes(array, comparator);
+ return new RegularImmutableSortedSet<E>(array, comparator);
+ }
+ }
+
+ /** Sort the array, according to the comparator. */
+ @SuppressWarnings("unchecked") // E comparator with Object array
+ private static <E> void sort(
+ Object[] array, Comparator<? super E> comparator) {
+ Arrays.sort(array, (Comparator<Object>) comparator);
+ }
+
+ /**
+ * Returns an array that removes duplicate consecutive elements, according to
+ * the provided comparator. Note that the input array is modified. This method
+ * does not support empty arrays.
+ */
+ private static <E> Object[] removeDupes(Object[] array,
+ Comparator<? super E> comparator) {
+ int size = 1;
+ for (int i = 1; i < array.length; i++) {
+ Object element = array[i];
+ if ((compare(comparator, array[size - 1], element) != 0)) {
+ array[size] = element;
+ size++;
+ }
+ }
+
+ // TODO: Move to ObjectArrays?
+ if (size == array.length) {
+ return array;
+ } else {
+ Object[] copy = new Object[size];
+ System.arraycopy(array, 0, copy, 0, size);
+ return copy;
+ }
+ }
+
+ /**
+ * Returns an immutable sorted set containing the given elements sorted by
+ * their natural ordering. When multiple elements are equivalent according to
+ * {@code compareTo()}, only the first one specified is included. To create a
+ * copy of a {@code SortedSet} that preserves the comparator, call
+ * {@link #copyOfSorted} instead.
+ *
+ * <p>Note that if {@code s} is a {@code Set<String>}, then
+ * {@code ImmutableSortedSet.copyOf(s)} returns a
+ * {@code ImmutableSortedSet<String>} containing each of the strings in
+ * {@code s}, while {@code ImmutableSortedSet.of(s)} returns a
+ * {@code ImmutableSortedSet<Set<String>>} containing one element (the given
+ * set itself).
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
+ * is an {@code ImmutableSortedSet}, it may be returned instead of a copy.
+ *
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ @SuppressWarnings("unchecked")
+ public static <E extends Comparable> ImmutableSortedSet<E> copyOf(
+ Iterable<? extends E> elements) {
+ return copyOfInternal(Comparators.naturalOrder(), elements, false);
+ }
+
+ /**
+ * Returns an immutable sorted set containing the given elements sorted by
+ * their natural ordering. When multiple elements are equivalent according to
+ * {@code compareTo()}, only the first one specified is included.
+ *
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ @SuppressWarnings("unchecked")
+ public static <E extends Comparable> ImmutableSortedSet<E> copyOf(
+ Iterator<? extends E> elements) {
+ return copyOfInternal(Comparators.naturalOrder(), elements);
+ }
+
+ /**
+ * Returns an immutable sorted set containing the elements of a sorted set,
+ * sorted by the same {@code Comparator}. That behavior differs from
+ * {@link #copyOf(Iterable)}, which always uses the natural ordering of the
+ * elements.
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if {@code sortedSet}
+ * is an {@code ImmutableSortedSet}, it may be returned instead of a copy.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> ImmutableSortedSet<E> copyOfSorted(SortedSet<E> sortedSet) {
+ Comparator<? super E> comparator = sortedSet.comparator();
+ if (comparator == null) {
+ comparator = NATURAL_ORDER;
+ }
+ return copyOfInternal(comparator, sortedSet, true);
+ }
+
+ private static <E> ImmutableSortedSet<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterable<? extends E> elements,
+ boolean fromSortedSet) {
+ boolean hasSameComparator
+ = fromSortedSet || hasSameComparator(elements, comparator);
+
+ if (hasSameComparator && (elements instanceof ImmutableSortedSet)) {
+ @SuppressWarnings("unchecked")
+ ImmutableSortedSet<E> result = (ImmutableSortedSet<E>) elements;
+ if (!result.hasPartialArray()) {
+ return result;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ Object[] array
+ = Iterables.newArray((Iterable<Object>) elements, Object.class);
+ if (array.length == 0) {
+ return emptySet(comparator);
+ }
+
+ for (Object e : array) {
+ checkNotNull(e);
+ }
+ if (!hasSameComparator) {
+ sort(array, comparator);
+ array = removeDupes(array, comparator);
+ }
+ return new RegularImmutableSortedSet<E>(array, comparator);
+ }
+
+ private static <E> ImmutableSortedSet<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterator<? extends E> elements) {
+ if (!elements.hasNext()) {
+ return emptySet(comparator);
+ }
+ List<E> list = Lists.newArrayList();
+ while (elements.hasNext()) {
+ list.add(checkNotNull(elements.next()));
+ }
+ Object[] array = list.toArray();
+ sort(array, comparator);
+ array = removeDupes(array, comparator);
+ return new RegularImmutableSortedSet<E>(array, comparator);
+ }
+
+ /**
+ * Returns {@code true} if {@code elements} is a {@code SortedSet} that uses
+ * {@code comparator} to order its elements. Note that equivalent comparators
+ * may still return {@code false}, if {@code equals} doesn't consider them
+ * equal. If one comparator is {@code null} and the other is
+ * {@link Comparators#naturalOrder()}, this method returns {@code true}.
+ */
+ private static boolean hasSameComparator(Object elements,
+ Comparator<?> comparator) {
+ if (elements instanceof SortedSet) {
+ SortedSet<?> sortedSet = (SortedSet<?>) elements;
+ Comparator<?> comparator2 = sortedSet.comparator();
+ return Objects.equal(comparator2, comparator)
+ || (comparator == null && comparator2 == Comparators.naturalOrder())
+ || (comparator2 == null && comparator == Comparators.naturalOrder());
+ }
+ return false;
+ }
+
+ /**
+ * Returns a factory that creates immutable sorted sets with an explicit
+ * comparator. If the comparator has a more general type than the set being
+ * generated, such as creating a {@code SortedSet<Integer>} with a
+ * {@code Comparator<Number>}, use the {@link Factory#Factory(Comparator)}
+ * constructor instead.
+ *
+ * @throws NullPointerException if {@code comparator} is null
+ */
+ public static <E> Factory<E> orderedBy(Comparator<E> comparator) {
+ return new Factory<E>(comparator);
+ }
+
+ /**
+ * Returns a factory that creates immutable sorted sets whose elements are
+ * ordered by the reverse of their natural ordering. The sorted sets use
+ * {@link Collections#reverseOrder()} as the comparator.
+ *
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
+ */
+ @SuppressWarnings("unchecked") // See method Javadoc
+ public static <E extends Comparable> Factory<E> reverseOrder() {
+ return new Factory<E>(Collections.reverseOrder());
+ }
+
+ /**
+ * A factory for creating immutable sorted sets with an explicit comparator.
+ *
+ * <p>The factory is immutable and may be used to create multiple
+ * {@code ImmutableSortedSet} instances.
+ */
+ public static class Factory<E> {
+ private final Comparator<? super E> comparator;
+
+ /**
+ * Creates a new factory. The returned factory is equivalent to the factory
+ * generated by {@link ImmutableSortedSet#orderedBy}.
+ *
+ * @throws NullPointerException if {@code comparator} is null
+ */
+ public Factory(Comparator<? super E> comparator) {
+ this.comparator = checkNotNull(comparator);
+ }
+
+ /**
+ * Returns an immutable sorted set containing the given elements sorted by
+ * the factory's comparator. When multiple elements are equivalent according
+ * to the comparator, only the first one specified is included.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public ImmutableSortedSet<E> of(E... elements) {
+ return ofInternal(comparator, elements);
+ }
+
+ /**
+ * Returns an immutable sorted set containing the given elements sorted by
+ * the factory's comparator. When multiple elements are equivalent according
+ * to the comparator, only the first one specified is included.
+ *
+ * <p><b>Note:</b> Despite what the method name suggests, if
+ * {@code elements} is an {@code ImmutableSortedSet} with an equivalent
+ * comparator, it may be returned instead of a copy.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public ImmutableSortedSet<E> copyOf(Iterable<? extends E> elements) {
+ return copyOfInternal(comparator, elements, false);
+ }
+
+ /**
+ * Returns an immutable sorted set containing the given elements sorted by
+ * the factory's comparator. When multiple elements are equivalent according
+ * to the comparator, only the first one specified is included.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ */
+ public ImmutableSortedSet<E> copyOf(Iterator<? extends E> elements) {
+ return copyOfInternal(comparator, elements);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <E> int compare(Comparator<? super E> comparator, Object a,
+ Object b) {
+ return comparator.compare((E) a, (E) b);
+ }
+
+ final Comparator<? super E> comparator;
+
+ private ImmutableSortedSet(Comparator<? super E> comparator) {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Returns the comparator that orders the elements, which is
+ * {@link Comparators#naturalOrder()} when the natural ordering of the
+ * elements is used. Note that its behavior is not consistent with
+ * {@link SortedSet#comparator()}, which returns {@code null} to indicate
+ * natural ordering.
+ */
+ public Comparator<? super E> comparator() {
+ return comparator;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method returns a serializable {@code ImmutableSortedSet}.
+ *
+ * <p>The {@link SortedSet#headSet} documentation states that a subset of a
+ * subset throws an {@link IllegalArgumentException} if passed a
+ * {@code toElement} greater than an earlier {@code toElement}. However, this
+ * method doesn't throw an exception in that situation, but instead keeps the
+ * original {@code toElement}.
+ */
+ public ImmutableSortedSet<E> headSet(E toElement) {
+ return headSetImpl(checkNotNull(toElement));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method returns a serializable {@code ImmutableSortedSet}.
+ *
+ * <p>The {@link SortedSet#subSet} documentation states that a subset of a
+ * subset throws an {@link IllegalArgumentException} if passed a
+ * {@code fromElement} smaller than an earlier {@code toElement}. However,
+ * this method doesn't throw an exception in that situation, but instead keeps
+ * the original {@code fromElement}. Similarly, this method keeps the
+ * original {@code toElement}, instead of throwing an exception, if passed a
+ * {@code toElement} greater than an earlier {@code toElement}.
+ */
+ public ImmutableSortedSet<E> subSet(E fromElement, E toElement) {
+ checkNotNull(fromElement);
+ checkNotNull(toElement);
+ checkArgument(compare(comparator, fromElement, toElement) <= 0);
+ return subSetImpl(fromElement, toElement);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method returns a serializable {@code ImmutableSortedSet}.
+ *
+ * <p>The {@link SortedSet#tailSet} documentation states that a subset of a
+ * subset throws an {@link IllegalArgumentException} if passed a
+ * {@code fromElement} smaller than an earlier {@code fromElement}. However,
+ * this method doesn't throw an exception in that situation, but instead keeps
+ * the original {@code fromElement}.
+ */
+ public ImmutableSortedSet<E> tailSet(E fromElement) {
+ return tailSetImpl(checkNotNull(fromElement));
+ }
+
+ /*
+ * These methods perform most headSet, subSet, and tailSet logic, besides
+ * parameter validation.
+ */
+ abstract ImmutableSortedSet<E> headSetImpl(E toElement);
+ abstract ImmutableSortedSet<E> subSetImpl(E fromElement, E toElement);
+ abstract ImmutableSortedSet<E> tailSetImpl(E fromElement);
+
+ /** Returns whether the elements are stored in a subset of a larger array. */
+ abstract boolean hasPartialArray();
+
+ /** An empty immutable sorted set. */
+ private static class EmptyImmutableSortedSet<E>
+ extends ImmutableSortedSet<E> {
+
+ EmptyImmutableSortedSet(Comparator<? super E> comparator) {
+ super(comparator);
+ }
+
+ public int size() {
+ return 0;
+ }
+
+ @Override public boolean isEmpty() {
+ return true;
+ }
+
+ @Override public boolean contains(Object target) {
+ return false;
+ }
+
+ public Iterator<E> iterator() {
+ return Iterators.emptyIterator();
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.EMPTY_ARRAY;
+ }
+
+ @Override public <T> T[] toArray(T[] a) {
+ if (a.length > 0) {
+ a[0] = null;
+ }
+ return a;
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ return targets.isEmpty();
+ }
+
+ @Override public boolean equals(Object object) {
+ return (object instanceof Set) && ((Set<?>) object).isEmpty();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public String toString() {
+ return "[]";
+ }
+
+ public E first() {
+ throw new NoSuchElementException();
+ }
+
+ public E last() {
+ throw new NoSuchElementException();
+ }
+
+ @Override ImmutableSortedSet<E> headSetImpl(E toElement) {
+ return this;
+ }
+
+ @Override ImmutableSortedSet<E> subSetImpl(E fromElement, E toElement) {
+ return this;
+ }
+
+ @Override ImmutableSortedSet<E> tailSetImpl(E fromElement) {
+ return this;
+ }
+
+ @Override boolean hasPartialArray() {
+ return false;
+ }
+ }
+
+ /**
+ * An empty immutable sorted set with one or more elements.
+ * TODO: Consider creating a separate class for a single-element sorted set.
+ */
+ @SuppressWarnings("serial")
+ private static final class RegularImmutableSortedSet<E>
+ extends ImmutableSortedSet<E> {
+
+ final Object[] elements;
+ /**
+ * The index of the first element that's in the sorted set (inclusive
+ * index).
+ */
+ final int fromIndex;
+ /**
+ * The index after the last element that's in the sorted set (exclusive
+ * index).
+ */
+ final int toIndex;
+
+ RegularImmutableSortedSet(Object[] elements,
+ Comparator<? super E> comparator) {
+ super(comparator);
+ this.elements = elements;
+ this.fromIndex = 0;
+ this.toIndex = elements.length;
+ }
+
+ RegularImmutableSortedSet(Object[] elements,
+ Comparator<? super E> comparator, int fromIndex, int toIndex) {
+ super(comparator);
+ this.elements = elements;
+ this.fromIndex = fromIndex;
+ this.toIndex = toIndex;
+ }
+
+ // The factory methods ensure that every element is an E.
+ @SuppressWarnings("unchecked")
+ public Iterator<E> iterator() {
+ return (Iterator<E>) Iterators.forArray(elements, fromIndex, size());
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ public int size() {
+ return toIndex - fromIndex;
+ }
+
+ @Override public boolean contains(Object o) {
+ if (o == null) {
+ return false;
+ }
+ try {
+ return binarySearch(o) >= 0;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ // TODO: For optimal performance, use a binary search when
+ // targets.size() < size() / log(size())
+ if (!hasSameComparator(targets, comparator()) || (targets.size() <= 1)) {
+ return super.containsAll(targets);
+ }
+
+ /*
+ * If targets is a sorted set with the same comparator, containsAll can
+ * run in O(n) time stepping through the two collections.
+ */
+ int i = fromIndex;
+ Iterator<?> iterator = targets.iterator();
+ Object target = iterator.next();
+
+ while (true) {
+ if (i >= toIndex) {
+ return false;
+ }
+
+ int cmp = compare(comparator, elements[i], target);
+
+ if (cmp < 0) {
+ i++;
+ } else if (cmp == 0) {
+ if (!iterator.hasNext()) {
+ return true;
+ }
+ target = iterator.next();
+ i++;
+ } else if (cmp > 0) {
+ return false;
+ }
+ }
+ }
+
+ int binarySearch(Object key) {
+ int lower = fromIndex;
+ int upper = toIndex - 1;
+
+ while (lower <= upper) {
+ int middle = lower + (upper - lower) / 2;
+ int c = compare(comparator, key, elements[middle]);
+ if (c < 0) {
+ upper = middle - 1;
+ } else if (c > 0) {
+ lower = middle + 1;
+ } else {
+ return middle;
+ }
+ }
+
+ return -lower - 1;
+ }
+
+ @Override public Object[] toArray() {
+ Object[] array = new Object[size()];
+ System.arraycopy(elements, fromIndex, array, 0, size());
+ return array;
+ }
+
+ // TODO: Move to ObjectArrays (same code in ImmutableList).
+ @Override public <T> T[] toArray(T[] array) {
+ int size = size();
+ if (array.length < size) {
+ array = ObjectArrays.newArray(array, size);
+ } else if (array.length > size) {
+ array[size] = null;
+ }
+ System.arraycopy(elements, fromIndex, array, 0, size);
+ return array;
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof Set)) {
+ return false;
+ }
+ Set<?> set = (Set<?>) object;
+ if (size() != set.size()) {
+ return false;
+ }
+
+ if (hasSameComparator(object, comparator)) {
+ Iterator<?> iterator = set.iterator();
+ try {
+ for (int i = fromIndex; i < toIndex; i++) {
+ Object otherElement = iterator.next();
+ if ((otherElement == null)
+ || (compare(comparator, elements[i], otherElement) != 0)) {
+ return false;
+ }
+ }
+ return true;
+ } catch (ClassCastException e) {
+ return false;
+ } catch (NoSuchElementException e) {
+ return false; // concurrent change to other set
+ }
+ }
+
+ return containsAll(set);
+ }
+
+ @Override public int hashCode() {
+ // not caching hash code since it could change if the elements are mutable
+ // in a way that modifies their hash codes
+ int hash = 0;
+ for (int i = fromIndex; i < toIndex; i++) {
+ hash += elements[i].hashCode();
+ }
+ return hash;
+ }
+
+ @Override public String toString() {
+ StringBuilder result = new StringBuilder(size() * 16);
+ result.append('[').append(elements[fromIndex]);
+ for (int i = fromIndex + 1; i < toIndex; i++) {
+ result.append(", ").append(elements[i]);
+ }
+ return result.append(']').toString();
+ }
+
+ // The factory methods ensure that every element is an E.
+ @SuppressWarnings("unchecked")
+ public E first() {
+ return (E) elements[fromIndex];
+ }
+
+ // The factory methods ensure that every element is an E.
+ @SuppressWarnings("unchecked")
+ public E last() {
+ return (E) elements[toIndex - 1];
+ }
+
+ @Override ImmutableSortedSet<E> headSetImpl(E toElement) {
+ return createSubset(fromIndex, findSubsetIndex(toElement));
+ }
+
+ @Override ImmutableSortedSet<E> subSetImpl(E fromElement, E toElement) {
+ return createSubset(
+ findSubsetIndex(fromElement), findSubsetIndex(toElement));
+ }
+
+ @Override ImmutableSortedSet<E> tailSetImpl(E fromElement) {
+ return createSubset(findSubsetIndex(fromElement), toIndex);
+ }
+
+ int findSubsetIndex(E fromElement) {
+ int index = binarySearch(fromElement);
+ return (index >= 0) ? index : (-index - 1);
+ }
+
+ ImmutableSortedSet<E> createSubset(int newFromIndex, int newToIndex) {
+ if (newFromIndex < newToIndex) {
+ return new RegularImmutableSortedSet<E>(elements, comparator,
+ newFromIndex, newToIndex);
+ } else {
+ return emptySet(comparator);
+ }
+ }
+
+ @Override boolean hasPartialArray() {
+ return (fromIndex != 0) || (toIndex != elements.length);
+ }
+ }
+
+ /*
+ * This class is used to serialize all ImmutableSortedSet instances,
+ * regardless of implementation type. It captures their "logical contents"
+ * only. This is necessary to ensure that the existence of a particular
+ * implementation type is an implementation detail.
+ */
+ private static class SerializedForm<E> implements Serializable {
+ final Comparator<? super E> comparator;
+ final Object[] elements;
+
+ public SerializedForm(Comparator<? super E> comparator, Object[] elements) {
+ this.comparator = comparator;
+ this.elements = elements;
+ }
+
+ @SuppressWarnings("unchecked")
+ Object readResolve() {
+ return new Factory<E>(comparator).of((E[]) elements);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException {
+ throw new InvalidObjectException("Use SerializedForm");
+ }
+
+ @Override Object writeReplace() {
+ return new SerializedForm<E>(comparator, toArray());
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterables.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterables.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterables.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,798 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Function;
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Objects;
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkContentsNotNull;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import org.richfaces.collections.base.Predicate;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * This class contains static utility methods that operate on or return objects
+ * of type {@code Iterable}. Also see the parallel implementations in {@link
+ * Iterators}.
+ *
+ * @author Kevin Bourrillion
+ * @author Scott Bonneau
+ */
+public final class Iterables {
+ private Iterables() {}
+
+ private static final Iterable<Object> EMPTY_ITERABLE = new Iterable<Object>()
+ {
+ public Iterator<Object> iterator() {
+ return Iterators.EMPTY_ITERATOR;
+ }
+ @Override public String toString() {
+ return "[]";
+ }
+ };
+
+ /** Returns the empty {@code Iterable}. */
+ // Casting to any type is safe since there are no actual elements.
+ @SuppressWarnings("unchecked")
+ public static <T> Iterable<T> emptyIterable() {
+ return (Iterable<T>) EMPTY_ITERABLE;
+ }
+
+ /** Returns an unmodifiable view of {@code iterable}. */
+ public static <T> Iterable<T> unmodifiableIterable(final Iterable<T> iterable)
+ {
+ checkNotNull(iterable);
+ return new Iterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.unmodifiableIterator(iterable.iterator());
+ }
+ @Override public String toString() {
+ return iterable.toString();
+ }
+ // no equals and hashCode; it would break the contract!
+ };
+ }
+
+ /**
+ * Returns the number of elements in {@code iterable}.
+ */
+ public static int size(Iterable<?> iterable) {
+ return (iterable instanceof Collection)
+ ? ((Collection<?>) iterable).size()
+ : Iterators.size(iterable.iterator());
+ }
+
+ /**
+ * Returns {@code true} if {@code iterable} contains {@code element}; that is,
+ * any object for while {@code equals(element)} is true.
+ */
+ public static boolean contains(Iterable<?> iterable, @Nullable Object element)
+ {
+ if (element == null) {
+ return containsNull(iterable);
+ }
+ if (iterable instanceof Collection) {
+ Collection<?> collection = (Collection<?>) iterable;
+ try {
+ return collection.contains(element);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ return Iterators.contains(iterable.iterator(), element);
+ }
+
+ /**
+ * Returns {@code true} if {@code iterable} contains at least one null
+ * element.
+ */
+ public static boolean containsNull(Iterable<?> iterable) {
+ if (iterable instanceof Collection) {
+ Collection<?> collection = (Collection<?>) iterable;
+ try {
+ return collection.contains(null);
+ } catch (NullPointerException e) {
+ return false;
+ }
+ }
+ return Iterators.containsNull(iterable.iterator());
+ }
+
+ /**
+ * Removes, from an iterable, every element that belongs to the provided
+ * collection.
+ *
+ * <p>This method calls {@link Collection#removeAll} if {@code iterable} is a
+ * collection, and {@link Iterators#removeAll} otherwise.
+ *
+ * @param iterable the iterable to (potentially) remove elements from
+ * @param c the elements to remove
+ * @return {@code true} if any elements are removed from {@code iterable}
+ */
+ public static boolean removeAll(Iterable<?> iterable, Collection<?> c) {
+ return (iterable instanceof Collection)
+ ? ((Collection<?>) iterable).removeAll(checkNotNull(c))
+ : Iterators.removeAll(iterable.iterator(), c);
+ }
+
+ /**
+ * Removes, from an iterable, every element that does not belong to the
+ * provided collection.
+ *
+ * <p>This method calls {@link Collection#retainAll} if {@code iterable} is a
+ * collection, and {@link Iterators#retainAll} otherwise.
+ *
+ * @param iterable the iterable to (potentially) remove elements from
+ * @param c the elements to retain
+ * @return {@code true} if any elements are removed from {@code iterable}
+ */
+ public static boolean retainAll(Iterable<?> iterable, Collection<?> c) {
+ return (iterable instanceof Collection)
+ ? ((Collection<?>) iterable).retainAll(checkNotNull(c))
+ : Iterators.retainAll(iterable.iterator(), c);
+ }
+
+ /**
+ * Determines whether two iterables contain equal elements in the same order.
+ * More specifically, this method returns {@code true} if {@code iterable1}
+ * and {@code iterable2} contain the same number of elements and every element
+ * of {@code iterable1} is equal to the corresponding element of
+ * {@code iterable2}.
+ */
+ public static boolean elementsEqual(
+ Iterable<?> iterable1, Iterable<?> iterable2) {
+ return Iterators.elementsEqual(iterable1.iterator(), iterable2.iterator());
+ }
+
+ /**
+ * Returns a string representation of {@code iterable}, with the format
+ * {@code [e1, e2, ..., en]}.
+ */
+ public static String toString(Iterable<?> iterable) {
+ return Iterators.toString(iterable.iterator());
+ }
+
+ /**
+ * Returns the single element contained in {@code iterable}.
+ *
+ * @throws NoSuchElementException if the iterable is empty
+ * @throws IllegalArgumentException if the iterable contains multiple
+ * elements
+ */
+ public static <T> T getOnlyElement(Iterable<T> iterable) {
+ return Iterators.getOnlyElement(iterable.iterator());
+ }
+
+ /**
+ * Returns the single element contained in {@code iterable}, or {@code
+ * defaultValue} if the iterable is empty.
+ *
+ * @throws IllegalArgumentException if the iterator contains multiple
+ * elements
+ */
+ public static <T> T getOnlyElement(
+ Iterable<T> iterable, @Nullable T defaultValue) {
+ return Iterators.getOnlyElement(iterable.iterator(), defaultValue);
+ }
+
+ /**
+ * Copies an iterable's elements into an array.
+ *
+ * @param iterable the iterable to copy
+ * @param type the type of the elements
+ * @return a newly-allocated array into which all the elements of the iterable
+ * have been copied
+ */
+ public static <T> T[] newArray(Iterable<T> iterable, Class<T> type) {
+ Collection<T> collection = (iterable instanceof Collection)
+ ? (Collection<T>) iterable
+ : Lists.newArrayList(iterable);
+ T[] array = ObjectArrays.newArray(type, collection.size());
+ return collection.toArray(array);
+ }
+
+ /**
+ * Adds all elements in {@code iterable} to {@code collection}.
+ *
+ * @return {@code true} if {@code collection} was modified as a result of this
+ * operation.
+ */
+ public static <T> boolean addAll(
+ Collection<T> collection, Iterable<? extends T> iterable) {
+ if (iterable instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<? extends T> c = (Collection<? extends T>) iterable;
+ return collection.addAll(c);
+ }
+ return Iterators.addAll(collection, iterable.iterator());
+ }
+
+ /**
+ * Returns the number of elements in the specified iterable that equal the
+ * specified object.
+ *
+ * @see Collections#frequency
+ */
+ public static int frequency(Iterable<?> iterable, @Nullable Object element) {
+ if ((iterable instanceof Multiset)) {
+ return ((Multiset<?>) iterable).count(element);
+ }
+ if ((iterable instanceof Set)) {
+ return ((Set<?>) iterable).contains(element) ? 1 : 0;
+ }
+ return Iterators.frequency(iterable.iterator(), element);
+ }
+
+ /**
+ * Returns an iterable whose iterator cycles indefinitely over the elements of
+ * {@code iterable}.
+ *
+ * <p>That iterator supports {@code remove()} if {@code iterable.iterator()}
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
+ * element, which is no longer in {@code iterable}. The iterator's
+ * {@code hasNext()} method returns {@code true} until {@code iterable} is
+ * empty.
+ *
+ * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an
+ * infinite loop. You should use an explicit {@code break} or be certain that
+ * you will eventually remove all the elements.
+ *
+ * <p>To cycle over the iterable {@code n} times, use the following:
+ * {@code Iterables.concat(Collections.nCopies(n, iterable))}
+ */
+ public static <T> Iterable<T> cycle(final Iterable<T> iterable) {
+ checkNotNull(iterable);
+ return new Iterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.cycle(iterable);
+ }
+ @Override public String toString() {
+ return iterable.toString() + " (cycled)";
+ }
+ };
+ }
+
+ /**
+ * Returns an iterable whose iterator cycles indefinitely over the provided
+ * elements.
+ *
+ * <p>That iterator supports {@code remove()} if {@code iterable.iterator()}
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
+ * element, but {@code elements} does not change. The iterator's
+ * {@code hasNext()} method returns {@code true} until all of the original
+ * elements have been removed.
+ *
+ * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an
+ * infinite loop. You should use an explicit {@code break} or be certain that
+ * you will eventually remove all the elements.
+ *
+ * <p>To cycle over the elements {@code n} times, use the following:
+ * {@code Iterables.concat(Collections.nCopies(n, Arrays.asList(elements)))}
+ */
+ public static <T> Iterable<T> cycle(T... elements) {
+ return cycle(Lists.newArrayList(elements));
+ }
+
+ /**
+ * Combines two iterables into a single iterable. The returned iterable has an
+ * iterator that traverses the elements in {@code a}, followed by the elements
+ * in {@code b}. The source iterators are not polled until necessary.
+ *
+ * <p>The returned iterable's iterator supports {@code remove()} when the
+ * corresponding input iterator supports it.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Iterable<T> concat(
+ Iterable<? extends T> a, Iterable<? extends T> b) {
+ checkNotNull(a);
+ checkNotNull(b);
+ return concat(Arrays.asList(a, b));
+ }
+
+ /**
+ * Combines multiple iterables into a single iterable. The returned iterable
+ * has an iterator that traverses the elements of each iterable in
+ * {@code inputs}. The input iterators are not polled until necessary.
+ *
+ * <p>The returned iterable's iterator supports {@code remove()} when the
+ * corresponding input iterator supports it.
+ *
+ * @throws NullPointerException if any of the provided iterables is null
+ */
+ public static <T> Iterable<T> concat(Iterable<? extends T>... inputs) {
+ return concat(checkContentsNotNull(Arrays.asList(inputs)));
+ }
+
+ /**
+ * Combines multiple iterables into a single iterable. The returned iterable
+ * has an iterator that traverses the elements of each iterable in
+ * {@code inputs}. The input iterators are not polled until necessary.
+ *
+ * <p>The returned iterable's iterator supports {@code remove()} when the
+ * corresponding input iterator supports it. The methods of the returned
+ * iterable may throw {@code NullPointerException} if any of the input
+ * iterators are null.
+ */
+ public static <T> Iterable<T> concat(
+ Iterable<? extends Iterable<? extends T>> inputs) {
+ /*
+ * Hint: if you let A represent Iterable<? extends T> and B represent
+ * Iterator<? extends T>, then this Function would look simply like:
+ *
+ * Function<A, B> function = new Function<A, B> {
+ * public B apply(A from) {
+ * return from.iterator();
+ * }
+ * }
+ *
+ * TODO: there may be a better way to do this.
+ */
+
+ Function<Iterable<? extends T>, Iterator<? extends T>> function
+ = new Function<Iterable<? extends T>, Iterator<? extends T>>() {
+ public Iterator<? extends T> apply(Iterable<? extends T> from) {
+ return from.iterator();
+ }
+ };
+ final Iterable<Iterator<? extends T>> iterators
+ = transform(inputs, function);
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.concat(iterators.iterator());
+ }
+ };
+ }
+
+ /**
+ * Partition an iterable into sub-iterables of the given size. For example,
+ * <code>{A, B, C, D, E, F}</code> with partition size 3 yields
+ * <code>{A, B, C}</code> and <code>{D, E, F}</code>. The returned iterables
+ * have iterators that do not support {@code remove()}.
+ *
+ * <p>After {@code next()} is called on the returned iterable's iterator, the
+ * iterables from prior {@code next()} calls become invalid.
+ *
+ * @param iterable the iterable to partition
+ * @param partitionSize the size of each partition
+ * @param padToSize whether to pad the last partition to the partition size
+ * with {@code null}.
+ * @return an iterable across partitioned iterables
+ */
+ public static <T> Iterable<Iterable<T>> partition(
+ final Iterable<? extends T> iterable, final int partitionSize,
+ final boolean padToSize) {
+ checkNotNull(iterable);
+ return new AbstractIterable<Iterable<T>>() {
+ public Iterator<Iterable<T>> iterator() {
+ final Iterator<Iterator<T>> iterator = Iterators.partition(
+ iterable.iterator(), partitionSize, padToSize);
+ return new AbstractIterator<Iterable<T>>() {
+ int howFarIn;
+
+ @Override protected Iterable<T> computeNext() {
+ howFarIn++;
+ if (!iterator.hasNext()) {
+ return endOfData();
+ }
+ return new AbstractIterable<T>() {
+ Iterator<T> innerIter = iterator.next();
+ boolean firstIteratorRequest = true;
+
+ public Iterator<T> iterator() {
+ if (firstIteratorRequest) {
+ firstIteratorRequest = false;
+ return innerIter;
+ } else {
+ Iterator<Iterator<T>> partitionIter = Iterators.partition(
+ iterable.iterator(), partitionSize, padToSize);
+ for (int i = 0; i < howFarIn; i++) {
+ innerIter = partitionIter.next();
+ }
+ return innerIter;
+ }
+ }
+ };
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Returns the elements of {@code unfiltered} that satisfy a predicate. The
+ * resulting iterable's iterator does not support {@code remove()}.
+ */
+ public static <T> Iterable<T> filter(
+ final Iterable<T> unfiltered, final Predicate<? super T> predicate) {
+ checkNotNull(unfiltered);
+ checkNotNull(predicate);
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.filter(unfiltered.iterator(), predicate);
+ }
+ };
+ }
+
+ /**
+ * Returns all instances of class {@code type} in {@code unfiltered}. The
+ * returned iterable has elements whose class is {@code type} or a subclass of
+ * {@code type}. The returned iterable's iterator does not support
+ * {@code remove()}.
+ *
+ * @param unfiltered an iterable containing objects of any type
+ * @param type the type of elements desired
+ * @return an unmodifiable iterable containing all elements of the original
+ * iterable that were of the requested type
+ */
+ public static <T> Iterable<T> filter(
+ final Iterable<?> unfiltered, final Class<T> type) {
+ checkNotNull(unfiltered);
+ checkNotNull(type);
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.filter(unfiltered.iterator(), type);
+ }
+ };
+ }
+
+ /**
+ * Returns {@code true} if one or more elements in {@code iterable} satisfy
+ * the predicate.
+ */
+ public static <T> boolean any(
+ Iterable<T> iterable, Predicate<? super T> predicate) {
+ return Iterators.any(iterable.iterator(), predicate);
+ }
+
+ /**
+ * Returns {@code true} if every element in {@code iterable} satisfies the
+ * predicate. If {@code iterable} is empty, {@code true} is returned.
+ */
+ public static <T> boolean all(
+ Iterable<T> iterable, Predicate<? super T> predicate) {
+ return Iterators.all(iterable.iterator(), predicate);
+ }
+
+ /**
+ * Returns the first element in {@code iterable} that satisfies the given
+ * predicate.
+ *
+ * @throws NoSuchElementException if no element in {@code iterable} matches
+ * the given predicate
+ */
+ public static <E> E find(Iterable<E> iterable,
+ Predicate<? super E> predicate) {
+ return Iterators.find(iterable.iterator(), predicate);
+ }
+
+ /**
+ * Returns an iterable that applies {@code function} to each element of {@code
+ * fromIterable}.
+ *
+ * <p>The returned iterable's iterator supports {@code remove()} if the
+ * provided iterator does. After a successful {@code remove()} call,
+ * {@code fromIterable} no longer contains the corresponding element.
+ */
+ public static <F, T> Iterable<T> transform(final Iterable<F> fromIterable,
+ final Function<? super F, ? extends T> function) {
+ checkNotNull(fromIterable);
+ checkNotNull(function);
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.transform(fromIterable.iterator(), function);
+ }
+ };
+ }
+
+ /**
+ * Returns the element at the specified position in an iterable.
+ *
+ * @param position position of the element to return
+ * @return the element at the specified position in {@code iterable}
+ * @throws IndexOutOfBoundsException if {@code position} is negative or
+ * greater than or equal to the size of {@code iterable}
+ */
+ public static <T> T get(Iterable<T> iterable, int position) {
+ checkNotNull(iterable);
+ if (position < 0) {
+ throw new IndexOutOfBoundsException(
+ "position cannot be negative: " + position);
+ }
+
+ if (iterable instanceof Collection) {
+ Collection<T> collection = (Collection<T>) iterable;
+ int size = collection.size();
+ if (position >= size) {
+ throw new IndexOutOfBoundsException(String.format(
+ "position %d must be less than the iterable size %d",
+ position, size));
+ }
+
+ if (iterable instanceof List) {
+ List<T> list = (List<T>) iterable;
+ return list.get(position);
+ }
+ }
+
+ return Iterators.get(iterable.iterator(), position);
+ }
+
+ /**
+ * Returns the last element of {@code iterable}.
+ *
+ * @return the last element of {@code iterable}
+ * @throws NoSuchElementException if the iterable has no elements
+ */
+ public static <T> T getLast(Iterable<T> iterable) {
+ if (iterable instanceof List) {
+ List<T> list = (List<T>) iterable;
+ // TODO: Support a concurrent list whose size changes while this method
+ // is running.
+ if (list.isEmpty()) {
+ throw new NoSuchElementException();
+ }
+ return list.get(list.size() - 1);
+ }
+
+ if (iterable instanceof SortedSet) {
+ SortedSet<T> sortedSet = (SortedSet<T>) iterable;
+ return sortedSet.last();
+ }
+
+ return Iterators.getLast(iterable.iterator());
+ }
+
+ /**
+ * Returns a view of {@code iterable} that skips its first
+ * {@code numberToSkip} elements. If {@code iterable} contains fewer than
+ * {@code numberToSkip} elements, the returned iterable skips all of its
+ * elements.
+ *
+ * <p>Modifications to the underlying {@link Iterable} before a call to
+ * {@code iterator()} are reflected in the returned iterator. That is, the
+ * iterator skips the first {@code numberToSkip} elements that exist when the
+ * {@code Iterator} is created, not when {@code skip()} is called.
+ *
+ * <p>The returned iterable's iterator supports {@code remove()} if the
+ * iterator of the underlying iterable supports it. Note that it is
+ * <i>not</i> possible to delete the last skipped element by immediately
+ * calling {@code remove()} on that iterator, as the {@code Iterator}
+ * contract states that a call to {@code remove()} before a call to
+ * {@code next()} will throw an {@link IllegalStateException}.
+ */
+ public static <T> Iterable<T> skip(final Iterable<T> iterable,
+ final int numberToSkip) {
+ checkNotNull(iterable);
+ checkArgument(numberToSkip >= 0, "number to skip cannot be negative");
+
+ if (iterable instanceof List) {
+ final List<T> list = (List<T>) iterable;
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ // TODO: Support a concurrent list whose size changes while this
+ // method is running.
+ return (numberToSkip >= list.size())
+ ? Iterators.<T>emptyIterator()
+ : list.subList(numberToSkip, list.size()).iterator();
+ }
+ };
+ }
+
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ final Iterator<T> iterator = iterable.iterator();
+
+ Iterators.skip(iterator, numberToSkip);
+
+ /*
+ * We can't just return the iterator because an immediate call to its
+ * remove() method would remove one of the skipped elements instead of
+ * throwing an IllegalStateException.
+ */
+ return new Iterator<T>() {
+ boolean atStart = true;
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ try {
+ return iterator.next();
+ } finally {
+ atStart = false;
+ }
+ }
+
+ public void remove() {
+ if (atStart) {
+ throw new IllegalStateException();
+ }
+ iterator.remove();
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Creates an iterable with the first {@code limitSize} elements of the given
+ * iterable. If the original iterable does not contain that many elements, the
+ * returned iterator will have the same behavior as the original iterable. The
+ * returned iterable's iterator supports {@code remove()} if the original
+ * iterator does.
+ *
+ * @param iterable the iterable to limit
+ * @param limitSize the maximum number of elements in the returned iterator
+ * @throws IllegalArgumentException if {@code limitSize} is negative
+ */
+ public static <T> Iterable<T> limit(
+ final Iterable<T> iterable, final int limitSize) {
+ checkNotNull(iterable);
+ checkArgument(limitSize >= 0, "limit is negative");
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ return Iterators.limit(iterable.iterator(), limitSize);
+ }
+ };
+ }
+
+ // Methods only in Iterables, not in Iterators
+
+ /**
+ * Adapts a list to an iterable with reversed iteration order. It is
+ * especially useful in foreach-style loops:
+ * <pre>
+ * List<String> mylist = ...
+ * for (String str : Iterables.reverse(mylist)) {
+ * ...
+ * } </pre>
+ *
+ * @return an iterable with the same elements as the list, in reverse.
+ */
+ public static <T> Iterable<T> reverse(final List<T> list) {
+ checkNotNull(list);
+ return new AbstractIterable<T>() {
+ public Iterator<T> iterator() {
+ final ListIterator<T> listIter = list.listIterator(list.size());
+ return new Iterator<T>() {
+ public boolean hasNext() {
+ return listIter.hasPrevious();
+ }
+ public T next() {
+ return listIter.previous();
+ }
+ public void remove() {
+ listIter.remove();
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Provides a rotated view of a list. Differs from {@link Collections#rotate}
+ * in that it leaves the underlying list unchanged. Note that this is a
+ * "live" view of the list that will change as the list changes. However, the
+ * behavior of an {@link Iterator} retrieved from a rotated view of the list
+ * is undefined if the list is structurally changed after the iterator is
+ * retrieved.
+ *
+ * @param list the list to return a rotated view of
+ * @param distance the distance to rotate the list. There are no constraints
+ * on this value; it may be zero, negative, or greater than {@code
+ * list.size()}.
+ * @return a rotated view of the given list
+ */
+ public static <T> Iterable<T> rotate(final List<T> list, final int distance) {
+ checkNotNull(list);
+
+
+ // If no rotation is requested, just return the original list
+ if (distance == 0) {
+ return list;
+ }
+
+ return new AbstractIterable<T>() {
+ /**
+ * Determines the actual distance we need to rotate (distance provided
+ * might be larger than the size of the list or negative).
+ */
+ int calcActualDistance(int size) {
+ // we already know distance and size are non-zero
+ int actualDistance = distance % size;
+ if (actualDistance < 0) {
+ // distance must have been negative
+ actualDistance += size;
+ }
+ return actualDistance;
+ }
+
+ public Iterator<T> iterator() {
+ int size = list.size();
+ if (size <= 1) {
+ return list.iterator();
+ }
+
+ int actualDistance = calcActualDistance(size);
+ // lists of a size that go into the distance evenly don't need rotation
+ if (actualDistance == 0) {
+ return list.iterator();
+ }
+
+ @SuppressWarnings("unchecked")
+ Iterable<T> rotated = concat(list.subList(actualDistance, size),
+ list.subList(0, actualDistance));
+ return rotated.iterator();
+ }
+ };
+ }
+
+ /**
+ * Returns whether the given iterable contains no elements.
+ *
+ * @return {@code true} if the iterable has no elements, {@code false} if the
+ * iterable has one or more elements
+ */
+ public static <T> boolean isEmpty(Iterable<T> iterable) {
+ return !iterable.iterator().hasNext();
+ }
+
+ /**
+ * Removes the specified element from the specified iterable.
+ *
+ * <p>This method iterates over the iterable, checking each element returned
+ * by the iterator in turn to see if it equals the object {@code o}. If they
+ * are equal, it is removed from the iterable with the iterator's
+ * {@code remove} method. At most one element is removed, even if the iterable
+ * contains multiple members that equal {@code o}.
+ *
+ * <p><b>Warning</b>: Do not use this method for a collection, such as a
+ * {@link HashSet}, that has a fast {@code remove} method.
+ *
+ * @param iterable the iterable from which to remove
+ * @param o an element to remove from the collection
+ * @return {@code true} if the iterable changed as a result
+ * @throws UnsupportedOperationException if the iterator does not support the
+ * {@code remove} method and the iterable contains the object
+ */
+ static boolean remove(Iterable<?> iterable, @Nullable Object o) {
+ Iterator<?> i = iterable.iterator();
+ while (i.hasNext()) {
+ if (Objects.equal(i.next(), o)) {
+ i.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterators.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterators.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Iterators.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,950 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkContentsNotNull;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+import org.richfaces.collections.base.Function;
+import org.richfaces.collections.base.Join;
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Objects;
+import org.richfaces.collections.base.Predicate;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * This class contains static utility methods that operate on or return objects
+ * of type {@code Iterator}. Also see the parallel implementations in {@link
+ * Iterables}.
+ *
+ * @author Kevin Bourrillion
+ * @author Scott Bonneau
+ */
+public final class Iterators {
+ private Iterators() {}
+
+ static final Iterator<Object> EMPTY_ITERATOR = new Iterator<Object>() {
+ public boolean hasNext() {
+ return false;
+ }
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+
+ /** Returns the empty {@code Iterator}. */
+ // Casting to any type is safe since there are no actual elements.
+ @SuppressWarnings("unchecked")
+ public static <T> Iterator<T> emptyIterator() {
+ return (Iterator<T>) EMPTY_ITERATOR;
+ }
+
+ private static final ListIterator<Object> EMPTY_LIST_ITERATOR =
+ new ListIterator<Object>() {
+ public boolean hasNext() {
+ return false;
+ }
+ public boolean hasPrevious() {
+ return false;
+ }
+ public int nextIndex() {
+ return 0;
+ }
+ public int previousIndex() {
+ return -1;
+ }
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+ public Object previous() {
+ throw new NoSuchElementException();
+ }
+ public void set(Object o) {
+ throw new UnsupportedOperationException();
+ }
+ public void add(Object o) {
+ throw new UnsupportedOperationException();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ /** Returns the empty {@code ListIterator}. */
+ // Casting to any type is safe since there are no actual elements.
+ @SuppressWarnings("unchecked")
+ public static <T> ListIterator<T> emptyListIterator() {
+ return (ListIterator<T>) EMPTY_LIST_ITERATOR;
+ }
+
+ private static final Iterator<Object> EMPTY_MODIFIABLE_ITERATOR =
+ new Iterator<Object>() {
+ /*@Override*/ public boolean hasNext() {
+ return false;
+ }
+
+ /*@Override*/ public Object next() {
+ throw new NoSuchElementException();
+ }
+
+ /*@Override*/ public void remove() {
+ throw new IllegalStateException();
+ }
+ };
+
+ /**
+ * Returns the empty {@code Iterator} that throws
+ * {@link IllegalStateException} instead of
+ * {@link UnsupportedOperationException} on a call to
+ * {@link Iterator#remove()}.
+ */
+ // Casting to any type is safe since there are no actual elements.
+ @SuppressWarnings("unchecked")
+ static <T> Iterator<T> emptyModifiableIterator() {
+ return (Iterator<T>) EMPTY_MODIFIABLE_ITERATOR;
+ }
+
+ /** Returns an unmodifiable view of {@code iterator}. */
+ public static <T> Iterator<T> unmodifiableIterator(
+ final Iterator<T> iterator) {
+ checkNotNull(iterator);
+ return new Iterator<T>() {
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ public T next() {
+ return iterator.next();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Returns the number of elements remaining in {@code iterator}. The iterator
+ * will be left exhausted: its {@code hasNext()} method will return
+ * {@code false}.
+ */
+ public static int size(Iterator<?> iterator) {
+ int count = 0;
+ while (iterator.hasNext()) {
+ iterator.next();
+ count++;
+ }
+ return count;
+ }
+
+ /**
+ * Returns {@code true} if {@code iterator} contains {@code element}.
+ */
+ public static boolean contains(Iterator<?> iterator, @Nullable Object element)
+ {
+ if (element == null) {
+ return containsNull(iterator);
+ }
+ while (iterator.hasNext()) {
+ if (element.equals(iterator.next())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code true} if {@code iterator} contains at least one null
+ * element.
+ */
+ public static boolean containsNull(Iterator<?> iterator) {
+ while (iterator.hasNext()) {
+ if (iterator.next() == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Traverses an iterator and removes every element that belongs to the
+ * provided collection. The iterator will be left exhausted: its
+ * {@code hasNext()} method will return {@code false}.
+ *
+ * @param iterator the iterator to (potentially) remove elements from
+ * @param c the elements to remove
+ * @return {@code true} if any elements are removed from {@code iterator}
+ */
+ public static boolean removeAll(Iterator<?> iterator, Collection<?> c) {
+ checkNotNull(c);
+ boolean modified = false;
+ while (iterator.hasNext()) {
+ if (c.contains(iterator.next())) {
+ iterator.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Traverses an iterator and removes every element that does not belong to the
+ * provided collection. The iterator will be left exhausted: its
+ * {@code hasNext()} method will return {@code false}.
+ *
+ * @param iterator the iterator to (potentially) remove elements from
+ * @param c the elements to retain
+ * @return {@code true} if any elements are removed from {@code iterator}
+ */
+ public static boolean retainAll(Iterator<?> iterator, Collection<?> c) {
+ checkNotNull(c);
+ boolean modified = false;
+ while (iterator.hasNext()) {
+ if (!c.contains(iterator.next())) {
+ iterator.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Determines whether two iterators contain equal elements in the same order.
+ * More specifically, this method returns {@code true} if {@code iterator1}
+ * and {@code iterator2} contain the same number of elements and every element
+ * of {@code iterator1} is equal to the corresponding element of
+ * {@code iterator2}.
+ *
+ * <p>Note that this will modify the supplied iterators, since they will have
+ * been advanced some number of elements forward.
+ */
+ public static boolean elementsEqual(
+ Iterator<?> iterator1, Iterator<?> iterator2) {
+ while (iterator1.hasNext()) {
+ if (!iterator2.hasNext()) {
+ return false;
+ }
+ Object o1 = iterator1.next();
+ Object o2 = iterator2.next();
+ if (!Objects.equal(o1, o2)) {
+ return false;
+ }
+ }
+ return !iterator2.hasNext();
+ }
+
+ /**
+ * Returns a string representation of {@code iterator}, with the format
+ * {@code [e1, e2, ..., en]}. The iterator will be left exhausted: its
+ * {@code hasNext()} method will return {@code false}.
+ */
+ public static String toString(Iterator<?> iterator) {
+ StringBuilder builder = new StringBuilder().append('[');
+ Join.join(builder, ", ", iterator);
+ return builder.append(']').toString();
+ }
+
+ /**
+ * Returns the single element contained in {@code iterator}.
+ *
+ * @throws NoSuchElementException if the iterator is empty
+ * @throws IllegalArgumentException if the iterator contains multiple
+ * elements. The state of the iterator is unspecified.
+ */
+ public static <T> T getOnlyElement(Iterator<T> iterator) {
+ T first = iterator.next();
+ if (!iterator.hasNext()) {
+ return first;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("expected one element but was: <" + first);
+ for (int i = 0; i < 4 && iterator.hasNext(); i++) {
+ sb.append(", " + iterator.next());
+ }
+ if (iterator.hasNext()) {
+ sb.append(", ...");
+ }
+ sb.append(">");
+
+ throw new IllegalArgumentException(sb.toString());
+ }
+
+ /**
+ * Returns the single element contained in {@code iterator}, or {@code
+ * defaultValue} if the iterator is empty.
+ *
+ * @throws IllegalArgumentException if the iterator contains multiple
+ * elements. The state of the iterator is unspecified.
+ */
+ public static <T> T getOnlyElement(
+ Iterator<T> iterator, @Nullable T defaultValue) {
+ return iterator.hasNext() ? getOnlyElement(iterator) : defaultValue;
+ }
+
+ /**
+ * Copies an iterator's elements into an array. The iterator will be left
+ * exhausted: its {@code hasNext()} method will return {@code false}.
+ *
+ * @param iterator the iterator to copy
+ * @param type the type of the elements
+ * @return a newly-allocated array into which all the elements of the iterator
+ * have been copied
+ */
+ public static <T> T[] newArray(
+ Iterator<? extends T> iterator, Class<T> type) {
+ List<T> list = Lists.newArrayList(iterator);
+ return Iterables.newArray(list, type);
+ }
+
+ /**
+ * Adds all elements in {@code iterator} to {@code collection}. The iterator
+ * will be left exhausted: its {@code hasNext()} method will return
+ * {@code false}.
+ *
+ * @return {@code true} if {@code collection} was modified as a result of this
+ * operation
+ */
+ public static <T> boolean addAll(
+ Collection<T> collection, Iterator<? extends T> iterator) {
+ checkNotNull(collection);
+ boolean wasModified = false;
+ while (iterator.hasNext()) {
+ wasModified |= collection.add(iterator.next());
+ }
+ return wasModified;
+ }
+
+ /**
+ * Returns the number of elements in the specified iterator that equal the
+ * specified object. The iterator will be left exhausted: its
+ * {@code hasNext()} method will return {@code false}.
+ *
+ * @see Collections#frequency
+ */
+ public static int frequency(Iterator<?> iterator, @Nullable Object element) {
+ int result = 0;
+ if (element == null) {
+ while (iterator.hasNext()) {
+ if (iterator.next() == null) {
+ result++;
+ }
+ }
+ } else {
+ while (iterator.hasNext()) {
+ if (element.equals(iterator.next())) {
+ result++;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns an iterator that cycles indefinitely over the elements of {@code
+ * iterable}.
+ *
+ * <p>The returned iterator supports {@code remove()} if the provided iterator
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
+ * element, which is no longer in {@code iterable}. The iterator's
+ * {@code hasNext()} method returns {@code true} until {@code iterable} is
+ * empty.
+ *
+ * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an
+ * infinite loop. You should use an explicit {@code break} or be certain that
+ * you will eventually remove all the elements.
+ */
+ public static <T> Iterator<T> cycle(final Iterable<T> iterable) {
+ checkNotNull(iterable);
+ return new Iterator<T>() {
+ Iterator<T> iterator = emptyIterator();
+ Iterator<T> removeFrom;
+
+ public boolean hasNext() {
+ if (!iterator.hasNext()) {
+ iterator = iterable.iterator();
+ }
+ return iterator.hasNext();
+ }
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ removeFrom = iterator;
+ return iterator.next();
+ }
+ public void remove() {
+ checkState(removeFrom != null,
+ "no calls to next() since last call to remove()");
+ removeFrom.remove();
+ removeFrom = null;
+ }
+ };
+ }
+
+ /**
+ * Returns an iterator that cycles indefinitely over the provided elements.
+ *
+ * <p>The returned iterator supports {@code remove()} if the provided iterator
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
+ * element, but {@code elements} does not change. The iterator's
+ * {@code hasNext()} method returns {@code true} until all of the original
+ * elements have been removed.
+ *
+ * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an
+ * infinite loop. You should use an explicit {@code break} or be certain that
+ * you will eventually remove all the elements.
+ */
+ public static <T> Iterator<T> cycle(T... elements) {
+ return cycle(Lists.newArrayList(elements));
+ }
+
+ /**
+ * Combines two iterators into a single iterator. The returned iterator
+ * iterates across the elements in {@code a}, followed by the elements in
+ * {@code b}. The source iterators are not polled until necessary.
+ *
+ * <p>The returned iterator supports {@code remove()} when the corresponding
+ * input iterator supports it.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Iterator<T> concat(Iterator<? extends T> a,
+ Iterator<? extends T> b) {
+ checkNotNull(a);
+ checkNotNull(b);
+ return concat(Arrays.asList(a, b).iterator());
+ }
+
+ /**
+ * Combines multiple iterators into a single iterator. The returned iterator
+ * iterates across the elements of each iterator in {@code inputs}. The input
+ * iterators are not polled until necessary.
+ *
+ * <p>The returned iterator supports {@code remove()} when the corresponding
+ * input iterator supports it.
+ *
+ * @throws NullPointerException if any of the provided iterators is null
+ */
+ public static <T> Iterator<T> concat(Iterator<? extends T>... inputs) {
+ return concat(checkContentsNotNull(Arrays.asList(inputs)).iterator());
+ }
+
+ /**
+ * Combines multiple iterators into a single iterator. The returned iterator
+ * iterates across the elements of each iterator in {@code inputs}. The input
+ * iterators are not polled until necessary.
+ *
+ * <p>The returned iterator supports {@code remove()} when the corresponding
+ * input iterator supports it. The methods of the returned iterator may throw
+ * {@code NullPointerException} if any of the input iterators are null.
+ */
+ public static <T> Iterator<T> concat(
+ final Iterator<? extends Iterator<? extends T>> inputs) {
+ checkNotNull(inputs);
+ return new Iterator<T>() {
+ Iterator<? extends T> current = emptyIterator();
+ Iterator<? extends T> removeFrom;
+
+ public boolean hasNext() {
+ while (!current.hasNext() && inputs.hasNext()) {
+ current = inputs.next();
+ }
+ return current.hasNext();
+ }
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ removeFrom = current;
+ return current.next();
+ }
+ public void remove() {
+ checkState(removeFrom != null,
+ "no calls to next() since last call to remove()");
+ removeFrom.remove();
+ removeFrom = null;
+ }
+ };
+ }
+
+ /**
+ * Partition an iterator into sub-iterators of the given size. For example,
+ * <code>{A, B, C, D, E, F}</code> with partition size 3 yields
+ * <code>{A, B, C}</code> and <code>{D, E, F}</code>. The returned
+ * iterators do not support {@code remove()}.
+ *
+ * <p>After {@code next()} is called on the returned iterator, the iterators
+ * from prior {@code next()} calls become invalid.
+ *
+ * @param iterator the iterator to partition
+ * @param partitionSize the size of each partition
+ * @param padToSize whether to pad the last partition to the partition size
+ * with {@code null}
+ * @return an iterator across partitioned iterators
+ */
+ public static <T> Iterator<Iterator<T>> partition(
+ final Iterator<? extends T> iterator,
+ final int partitionSize, final boolean padToSize) {
+ checkNotNull(iterator);
+ return new AbstractIterator<Iterator<T>>() {
+ Iterator<T> currentRow;
+
+ @Override protected Iterator<T> computeNext() {
+ if (currentRow != null) {
+ while (currentRow.hasNext()) {
+ currentRow.next();
+ }
+ }
+ if (!iterator.hasNext()) {
+ return endOfData();
+ }
+ currentRow = new AbstractIterator<T>() {
+ int count = partitionSize;
+
+ @Override protected T computeNext() {
+ if (count == 0) {
+ return endOfData();
+ }
+ count--;
+ if (iterator.hasNext()) {
+ return iterator.next();
+ } else {
+ if (!padToSize) {
+ endOfData();
+ }
+ return null;
+ }
+ }
+ };
+ return currentRow;
+ }
+ };
+ }
+
+ /**
+ * Returns the elements of {@code unfiltered} that satisfy a predicate. The
+ * resulting iterator does not support {@code remove()}.
+ */
+ public static <T> Iterator<T> filter(
+ final Iterator<T> unfiltered, final Predicate<? super T> predicate) {
+ checkNotNull(unfiltered);
+ checkNotNull(predicate);
+ return new AbstractIterator<T>() {
+ @Override protected T computeNext() {
+ while (unfiltered.hasNext()) {
+ T element = unfiltered.next();
+ if (predicate.apply(element)) {
+ return element;
+ }
+ }
+ return endOfData();
+ }
+ };
+ }
+
+ /**
+ * Returns all instances of class {@code type} in {@code unfiltered}. The
+ * returned iterator has elements whose class is {@code type} or a subclass of
+ * {@code type}. The returned iterator does not support {@code remove()}.
+ *
+ * @param unfiltered an iterator containing objects of any type
+ * @param type the type of elements desired
+ * @return an unmodifiable iterator containing all elements of the original
+ * iterator that were of the requested type
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Iterator<T> filter(
+ Iterator<?> unfiltered, final Class<T> type) {
+ checkNotNull(type);
+ Predicate<Object> predicate = new Predicate<Object>() {
+ public boolean apply(Object object) {
+ return type.isInstance(object);
+ }
+ };
+ return (Iterator<T>) filter(unfiltered, predicate);
+ }
+
+ /**
+ * Returns {@code true} if one or more elements returned by {@code iterator}
+ * satisfy the given predicate.
+ */
+ public static <T> boolean any(
+ Iterator<T> iterator, Predicate<? super T> predicate) {
+ checkNotNull(predicate);
+ while (iterator.hasNext()) {
+ T element = iterator.next();
+ if (predicate.apply(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code true} if every element returned by {@code iterator}
+ * satisfies the given predicate. If {@code iterator} is empty, {@code true}
+ * is returned.
+ */
+ public static <T> boolean all(
+ Iterator<T> iterator, Predicate<? super T> predicate) {
+ checkNotNull(predicate);
+ while (iterator.hasNext()) {
+ T element = iterator.next();
+ if (!predicate.apply(element)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the first element in {@code iterator} that satisfies the given
+ * predicate. If a matching element is found, the iterator will be left in a
+ * state such that calling {@code iterator.remove()} will remove the found
+ * item. If no such element is found, the iterator will be left exhausted: its
+ * {@code hasNext()} method will return {@code false}.
+ *
+ * @return the first matching element in {@code iterator}
+ * @throws NoSuchElementException if no element in {@code iterator} matches
+ * the given predicate
+ */
+ public static <E> E find(Iterator<E> iterator, Predicate<? super E> predicate)
+ {
+ return filter(iterator, predicate).next();
+ }
+
+ /**
+ * Returns an iterator that applies {@code function} to each element of {@code
+ * fromIterator}.
+ *
+ * <p>The returned iterator supports {@code remove()} if the provided iterator
+ * does. After a successful {@code remove()} call, {@code fromIterator} no
+ * longer contains the corresponding element.
+ */
+ public static <F, T> Iterator<T> transform(final Iterator<F> fromIterator,
+ final Function<? super F, ? extends T> function) {
+ checkNotNull(fromIterator);
+ checkNotNull(function);
+ return new Iterator<T>() {
+ public boolean hasNext() {
+ return fromIterator.hasNext();
+ }
+ public T next() {
+ F from = fromIterator.next();
+ return function.apply(from);
+ }
+ public void remove() {
+ fromIterator.remove();
+ }
+ };
+ }
+
+ /**
+ * Advances {@code iterator} {@code position + 1} times, returning the element
+ * at the {@code position}th position.
+ *
+ * @param position position of the element to return
+ * @return the element at the specified position in {@code iterator}
+ * @throws IndexOutOfBoundsException if {@code position} is negative or
+ * greater than or equal to the number of elements remaining in
+ * {@code iterator}
+ */
+ public static <T> T get(Iterator<T> iterator, int position) {
+ checkNotNull(iterator);
+ if (position < 0) {
+ throw new IndexOutOfBoundsException(
+ "position cannot be negative: " + position);
+ }
+
+ int skipped = skip(iterator, position);
+ if (skipped < position || !iterator.hasNext()) {
+ throw new IndexOutOfBoundsException(String.format(
+ "position (%d) must be less than the number of elements that " +
+ "remained (%d)", position, skipped));
+ } else {
+ return iterator.next();
+ }
+ }
+
+ /**
+ * Advances {@code iterator} to the end, returning the last element.
+ *
+ * @return the last element of {@code iterator}
+ * @throws NoSuchElementException if the iterator has no remaining elements
+ */
+ public static <T> T getLast(Iterator<T> iterator) {
+ while (true) {
+ T current = iterator.next();
+ if (!iterator.hasNext()) {
+ return current;
+ }
+ }
+ }
+
+ /**
+ * Calls {@code next()} on {@code iterator}, either {@code numberToSkip} times
+ * or until {@code hasNext()} returns {@code false}, whichever comes first.
+ *
+ * @return the number of elements skipped
+ */
+ public static <T> int skip(Iterator<T> iterator, int numberToSkip) {
+ checkNotNull(iterator);
+ checkArgument(numberToSkip >= 0, "number to skip cannot be negative");
+
+ int i;
+ for (i = 0; i < numberToSkip && iterator.hasNext(); i++) {
+ iterator.next();
+ }
+ return i;
+ }
+
+ /**
+ * Creates an iterator returning the first {@code limitSize} elements of the
+ * given iterator. If the original iterator does not contain that many
+ * elements, the returned iterator will have the same behavior as the original
+ * iterator. The returned iterator supports {@code remove()} if the original
+ * iterator does.
+ *
+ * @param iterator the iterator to limit
+ * @param limitSize the maximum number of elements in the returned iterator
+ * @throws IllegalArgumentException if {@code limitSize} is negative
+ */
+ public static <T> Iterator<T> limit(
+ final Iterator<T> iterator, final int limitSize) {
+ checkNotNull(iterator);
+ checkArgument(limitSize >= 0, "limit is negative");
+ return new Iterator<T>() {
+ private int count;
+
+ public boolean hasNext() {
+ return count < limitSize && iterator.hasNext();
+ }
+
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ count++;
+ return iterator.next();
+ }
+
+ public void remove() {
+ iterator.remove();
+ }
+ };
+ }
+
+ // Methods only in Iterators, not in Iterables
+
+ /**
+ * Returns an iterator containing the elements of {@code array} in order. Note
+ * that you can also use the iterator of {@link Arrays#asList}.
+ */
+ static <T> Iterator<T> forArray(T[] array) {
+ return forArray(array, 0, array.length);
+ }
+
+ /**
+ * Returns an iterator containing the elements in the specified range of
+ * {@code array} in order.
+ *
+ * @param array array to read elements out of
+ * @param offset index of first array element to retrieve
+ * @length length number of elements in iteration
+ *
+ * @throws IndexOutOfBoundsException if {@code offset} is negative,
+ * {@code length} is negative, or {@code offset + length > array.length}
+ */
+ public static <T> Iterator<T> forArray(
+ final T[] array, final int offset, final int length) {
+ checkNotNull(array);
+ if (length < 0) {
+ throw new IndexOutOfBoundsException("Negative length " + length);
+ }
+ if (offset < 0) {
+ throw new IndexOutOfBoundsException("Negative offset " + offset);
+ }
+ if (offset + length > array.length) {
+ throw new IndexOutOfBoundsException(
+ "offset (" + offset + ") + length (" + length + ") > "
+ + "array.length (" + array.length + ")");
+ }
+ if (length == 0) {
+ return emptyIterator();
+ }
+ return new Iterator<T>() {
+ int i = offset;
+ public boolean hasNext() {
+ return i < offset + length;
+ }
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return array[i++];
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Returns an iterator containing only {@code value}.
+ */
+ static <T> Iterator<T> singletonIterator(final T value) {
+ return new Iterator<T>() {
+ boolean done;
+ public boolean hasNext() {
+ return !done;
+ }
+ public T next() {
+ if (done) {
+ throw new NoSuchElementException();
+ }
+ done = true;
+ return value;
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Adapts an {@code Enumeration} to the {@code Iterator} interface. The
+ * returned iterator does not support {@code remove()}.
+ */
+ public static <T> Iterator<T> forEnumeration(final Enumeration<T> enumeration)
+ {
+ checkNotNull(enumeration);
+ return new Iterator<T>() {
+ public boolean hasNext() {
+ return enumeration.hasMoreElements();
+ }
+ public T next() {
+ return enumeration.nextElement();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Adapts an {@code Iterator} to the {@code Enumeration} interface.
+ *
+ * @see Collections#enumeration(Collection)
+ */
+ public static <T> Enumeration<T> asEnumeration(final Iterator<T> iterator) {
+ checkNotNull(iterator);
+ return new Enumeration<T>() {
+ public boolean hasMoreElements() {
+ return iterator.hasNext();
+ }
+ public T nextElement() {
+ return iterator.next();
+ }
+ };
+ }
+
+ /**
+ * Implementation of PeekingIterator that avoids peeking unless necessary.
+ */
+ private static class PeekingImpl<E> implements PeekingIterator<E> {
+
+ private final Iterator<? extends E> iterator;
+ private boolean hasPeeked;
+ private E peekedElement;
+
+ public PeekingImpl(Iterator<? extends E> iterator) {
+ this.iterator = checkNotNull(iterator);
+ }
+
+ public boolean hasNext() {
+ return hasPeeked || iterator.hasNext();
+ }
+
+ public E next() {
+ if (!hasPeeked) {
+ return iterator.next();
+ }
+ E result = peekedElement;
+ hasPeeked = false;
+ peekedElement = null;
+ return result;
+ }
+
+ public void remove() {
+ checkState(!hasPeeked, "Can't remove after you've peeked at next");
+ iterator.remove();
+ }
+
+ public E peek() {
+ if (!hasPeeked) {
+ peekedElement = iterator.next();
+ hasPeeked = true;
+ }
+ return peekedElement;
+ }
+ }
+
+ /**
+ * Wraps the supplied iterator in a {@code PeekingIterator}. The
+ * {@link PeekingIterator} assumes ownership of the supplied iterator, so
+ * users should cease making direct calls to it after calling this method.
+ *
+ * <p>If the {@link PeekingIterator#peek()} method of the constructed
+ * {@code PeekingIterator} is never called, the returned iterator will
+ * behave exactly the same as the supplied iterator.
+ *
+ * <p>Subsequent calls to {@code peek()} with no intervening calls to
+ * {@code next()} do not affect the iteration, and hence return the same
+ * object each time. After a call to {@code peek()}, the next call to
+ * {@code next()} is guaranteed to return the same object that the
+ * {@code peek()} call returned. For example:
+ *
+ * <pre>
+ * PeekingIterator<E> peekingIterator = ...;
+ * // Either the next three calls will each throw
+ * // NoSuchElementExceptions, or...
+ * E e1 = peekingIterator.peek();
+ * E e2 = peekingIterator.peek(); // e2 is the same as e1
+ * E e3 = peekingIterator.next(); // e3 is the same as e1/e2
+ * </pre>
+ *
+ * <p>Calling {@link Iterator#remove()} after {@link PeekingIterator#peek()}
+ * is unsupported by the returned iterator and will throw an
+ * {@link IllegalStateException}.
+ */
+ public static <T> PeekingIterator<T> peekingIterator(
+ Iterator<? extends T> iterator) {
+ return new PeekingImpl<T>(iterator);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Implementation of {@code Multimap} that does not allow duplicate key-value
+ * entries and that returns collections whose iterators follow the ordering in
+ * which the data was added to the multimap.
+ *
+ * <p>The collections returned by {@code keySet}, {@code keys}, and {@code
+ * asMap} iterate through the keys in the order they were first added to the
+ * multimap. Similarly, {@code get}, {@code removeAll}, and {@code
+ * replaceValues} return collections that iterate through the values in the
+ * order they were added. The collections generated by {@code entries} and
+ * {@code values} iterate across the key-value mappings in the order they were
+ * added to the multimap.
+ *
+ * <p>The iteration ordering of the collections generated by {@code keySet},
+ * {@code keys}, and {@code asMap} has a few subtleties. As long as the set of
+ * keys remains unchanged, adding or removing mappings does not affect the key
+ * iteration order. However, if you remove all values associated with a key and
+ * then add the key back to the multimap, that key will come last in the key
+ * iteration order.
+ *
+ * <p>The multimap does not store duplicate key-value pairs. Adding a new
+ * key-value pair equal to an existing key-value pair has no effect.
+ *
+ * <p>Keys and values may be null. All optional multimap methods are supported,
+ * and all returned views are modifiable.
+ *
+ * <p>This class is not threadsafe when any concurrent operations update the
+ * multimap. Concurrent read operations will work correctly. To allow concurrent
+ * update operations, wrap your multimap with a call to {@link
+ * Multimaps#synchronizedSetMultimap}.
+ *
+ * @author Jared Levy
+ */
+public final class LinkedHashMultimap<K, V> extends StandardSetMultimap<K, V> {
+ /**
+ * Map entries with an iteration order corresponding to the order in which the
+ * key-value pairs were added to the multimap.
+ */
+ private transient Collection<Map.Entry<K, V>> linkedEntries;
+
+ /** Constructs an empty {@code LinkedHashMultimap}. */
+ public LinkedHashMultimap() {
+ super(new LinkedHashMap<K, Collection<V>>());
+ linkedEntries = Sets.newLinkedHashSet();
+ }
+
+ /**
+ * Constructs a {@code LinkedHashMultimap} with the same mappings as the
+ * specified {@code Multimap}. If a key-value mapping appears multiple times
+ * in the input multimap, it only appears once in the constructed multimap.
+ * The new multimap has the same {@link Multimap#entries()} iteration order as
+ * the input multimap, except for excluding duplicate mappings.
+ */
+ public LinkedHashMultimap(Multimap<? extends K, ? extends V> multimap) {
+ super(new LinkedHashMap<K, Collection<V>>(
+ Maps.capacity(multimap.keySet().size())));
+ linkedEntries
+ = new LinkedHashSet<Map.Entry<K, V>>(Maps.capacity(multimap.size()));
+ putAll(multimap);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Creates an empty {@code LinkedHashSet} for a collection of values for
+ * one key.
+ *
+ * @return a new {@code LinkedHashSet} containing a collection of values for
+ * one key
+ */
+ @Override Set<V> createCollection() {
+ return new LinkedHashSet<V>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Creates a decorated {@code LinkedHashSet} that also keeps track of the
+ * order in which key-value pairs are added to the multimap.
+ *
+ * @param key key to associate with values in the collection
+ * @return a new decorated {@code LinkedHashSet} containing a collection of
+ * values for one key
+ */
+ @Override Collection<V> createCollection(@Nullable K key) {
+ return new SetDecorator(key, createCollection());
+ }
+
+ private class SetDecorator extends ForwardingSet<V> {
+ final Set<V> delegate;
+ final K key;
+
+ SetDecorator(K key, Set<V> delegate) {
+ this.delegate = delegate;
+ this.key = key;
+ }
+
+ @Override protected Set<V> delegate() {
+ return delegate;
+ }
+
+ <E> Map.Entry<K, E> createEntry(@Nullable E value) {
+ return Maps.immutableEntry(key, value);
+ }
+
+ <E> Collection<Map.Entry<K, E>> createEntries(Collection<E> values) {
+ // converts a collection of values into a list of key/value map entries
+ Collection<Map.Entry<K, E>> entries
+ = Lists.newArrayListWithExpectedSize(values.size());
+ for (E value : values) {
+ entries.add(createEntry(value));
+ }
+ return entries;
+ }
+
+ @Override public boolean add(@Nullable V value) {
+ boolean changed = delegate.add(value);
+ if (changed) {
+ linkedEntries.add(createEntry(value));
+ }
+ return changed;
+ }
+
+ @Override public boolean addAll(Collection<? extends V> values) {
+ boolean changed = delegate.addAll(values);
+ if (changed) {
+ linkedEntries.addAll(createEntries(delegate()));
+ }
+ return changed;
+ }
+
+ @Override public void clear() {
+ linkedEntries.removeAll(createEntries(delegate()));
+ delegate.clear();
+ }
+
+ @Override public Iterator<V> iterator() {
+ final Iterator<V> delegateIterator = delegate.iterator();
+ return new Iterator<V>() {
+ V value;
+
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+ public V next() {
+ value = delegateIterator.next();
+ return value;
+ }
+ public void remove() {
+ delegateIterator.remove();
+ linkedEntries.remove(createEntry(value));
+ }
+ };
+ }
+
+ @Override public boolean remove(@Nullable Object value) {
+ boolean changed = delegate.remove(value);
+ if (changed) {
+ /*
+ * linkedEntries.remove() will return false when this method is called
+ * by entries().iterator().remove()
+ */
+ linkedEntries.remove(createEntry(value));
+ }
+ return changed;
+ }
+
+ @Override public boolean removeAll(Collection<?> values) {
+ boolean changed = delegate.removeAll(values);
+ if (changed) {
+ linkedEntries.removeAll(createEntries(values));
+ }
+ return changed;
+ }
+
+ @Override public boolean retainAll(Collection<?> values) {
+ /*
+ * Calling linkedEntries.retainAll() would incorrectly remove values
+ * with other keys.
+ */
+ boolean changed = false;
+ Iterator<V> iterator = delegate.iterator();
+ while (iterator.hasNext()) {
+ V value = iterator.next();
+ if (!values.contains(value)) {
+ iterator.remove();
+ linkedEntries.remove(Maps.immutableEntry(key, value));
+ changed = true;
+ }
+ }
+ return changed;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Generates an iterator across map entries that follows the ordering in
+ * which the key-value pairs were added to the multimap.
+ *
+ * @return a key-value iterator with the correct ordering
+ */
+ @Override Iterator<Map.Entry<K, V>> createEntryIterator() {
+ final Iterator<Map.Entry<K, V>> delegateIterator = linkedEntries.iterator();
+
+ return new Iterator<Map.Entry<K, V>>() {
+ Map.Entry<K, V> entry;
+
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+
+ public Map.Entry<K, V> next() {
+ entry = delegateIterator.next();
+ return entry;
+ }
+
+ public void remove() {
+ // Remove from iterator first to keep iterator valid.
+ delegateIterator.remove();
+ LinkedHashMultimap.this.remove(entry.getKey(), entry.getValue());
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>If {@code values} is not empty and the multimap already contains a
+ * mapping for {@code key}, the {@code keySet()} ordering is unchanged.
+ * However, the provided values always come last in the {@link #entries()} and
+ * {@link #values()} iteration orderings.
+ */
+ @Override public Set<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
+ return super.replaceValues(key, values);
+ }
+
+ /**
+ * Returns a set of all key-value pairs. Changes to the returned set will
+ * update the underlying multimap, and vice versa. The entries set does not
+ * support the {@code add} or {@code addAll} operations.
+ *
+ * <p>The iterator generated by the returned set traverses the entries in the
+ * order they were added to the multimap.
+ */
+ @Override public Set<Map.Entry<K, V>> entries() {
+ return super.entries();
+ }
+
+ /**
+ * Returns a collection of all values in the multimap. Changes to the returned
+ * collection will update the underlying multimap, and vice versa.
+ *
+ * <p>The iterator generated by the returned collection traverses the values
+ * in the order they were added to the multimap.
+ */
+ @Override public Collection<V> values() {
+ return super.values();
+ }
+
+ // Unfortunately, the entries() ordering does not determine the key ordering;
+ // see the example in the LinkedListMultimap class Javadoc.
+
+ /**
+ * @serialData the number of distinct keys, and then for each distinct key:
+ * the first key, the number of values for that key, and the key's values,
+ * followed by successive keys and values from the entries() ordering
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMultimap(this, stream);
+ for (Map.Entry<K, V> entry : linkedEntries) {
+ stream.writeObject(entry.getKey());
+ stream.writeObject(entry.getValue());
+ }
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setMap(new LinkedHashMap<K, Collection<V>>());
+ linkedEntries = Sets.newLinkedHashSet();
+ Serialization.populateMultimap(this, stream);
+ linkedEntries.clear(); // will clear and repopulate entries
+ for (int i = 0; i < size(); i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ K key = (K) stream.readObject();
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ V value = (V) stream.readObject();
+ linkedEntries.add(Maps.immutableEntry(key, value));
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/LinkedHashMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.LinkedHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A {@code Multiset} implementation with predictable iteration order. Its
+ * iterator orders elements according to when the first occurrence of the
+ * element was added. When the multiset contains multiple instances of an
+ * element, those instances are consecutive in the iteration order. If all
+ * occurrences of an element are removed, after which that element is added to
+ * the multiset, the element will appear at the end of the iteration.
+ *
+ * @author Kevin Bourrillion
+ * @author Jared Levy
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public final class LinkedHashMultiset<E> extends AbstractMapBasedMultiset<E> {
+ /**
+ * Constructs a new empty {@code LinkedHashMultiset} using the default initial
+ * capacity (16 distinct elements) and load factor (0.75).
+ */
+ public LinkedHashMultiset() {
+ super(new LinkedHashMap<E, AtomicInteger>());
+ }
+
+ /**
+ * Constructs a new empty {@code LinkedHashMultiset} with the specified
+ * expected number of distinct elements and the default load factor (0.75).
+ *
+ * @param distinctElements the expected number of distinct elements
+ * @throws IllegalArgumentException if {@code distinctElements} is negative
+ */
+ public LinkedHashMultiset(int distinctElements) {
+ // Could use newLinkedHashMapWithExpectedSize() if it existed
+ super(new LinkedHashMap<E, AtomicInteger>(Maps.capacity(distinctElements)));
+ }
+
+ /**
+ * Constructs a new {@code LinkedHashMultiset} containing the specified
+ * elements.
+ *
+ * @param elements the elements that the multiset should contain
+ */
+ public LinkedHashMultiset(Iterable<? extends E> elements) {
+ this(Multisets.inferDistinctElements(elements));
+ Iterables.addAll(this, elements); // careful if we make this class non-final
+ }
+
+ /**
+ * @serialData the number of distinct elements, the first element, its count,
+ * the second element, its count, and so on
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ Serialization.writeMultiset(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setBackingMap(new LinkedHashMap<E, AtomicInteger>());
+ Serialization.populateMultiset(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ListMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ListMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ListMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@code Multimap} that can hold duplicate key-value pairs and that maintains
+ * the insertion ordering of values for a given key.
+ *
+ * <p>The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods
+ * each return a {@link List} of values. Though the method signature doesn't say
+ * so explicitly, the map returned by {@link #asMap} has {@code List} values.
+ *
+ * @author Jared Levy
+ */
+public interface ListMultimap<K, V> extends Multimap<K, V> {
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because the values for a given key may have duplicates and follow the
+ * insertion ordering, this method returns a {@link List}, instead of the
+ * {@link java.util.Collection} specified in the {@link Multimap} interface.
+ */
+ List<V> get(@Nullable K key);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because the values for a given key may have duplicates and follow the
+ * insertion ordering, this method returns a {@link List}, instead of the
+ * {@link java.util.Collection} specified in the {@link Multimap} interface.
+ */
+ List<V> removeAll(@Nullable Object key);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because the values for a given key may have duplicates and follow the
+ * insertion ordering, this method returns a {@link List}, instead of the
+ * {@link java.util.Collection} specified in the {@link Multimap} interface.
+ */
+ List<V> replaceValues(K key, Iterable<? extends V> values);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Though the method signature doesn't say so explicitly, the returned map
+ * has {@link List} values.
+ */
+ Map<K, Collection<V>> asMap();
+
+ /**
+ * Compares the specified object to this multimap for equality.
+ *
+ * <p>Two {@code ListMultimap} instances are equal if, for each key, they
+ * contain the same values in the same order. If the value orderings disagree,
+ * the multimaps will not be considered equal.
+ */
+ boolean equals(@Nullable Object obj);
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Lists.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Lists.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Lists.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Function;
+import org.richfaces.collections.base.Nullable;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.AbstractSequentialList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+
+/**
+ * Static utility methods pertaining to {@link List} instances. Also see this
+ * class's counterparts {@link Sets} and {@link Maps}.
+ *
+ * @author Kevin Bourrillion
+ * @author Mike Bostock
+ */
+public final class Lists {
+ private Lists() {}
+
+ // ArrayList
+
+ /**
+ * Creates an empty {@code ArrayList} instance.
+ *
+ * <p><b>Note:</b> if you need an immutable empty list, use {@link
+ * Collections#emptyList} instead.
+ *
+ * @return a newly-created, initially-empty {@code ArrayList}
+ */
+ public static <E> ArrayList<E> newArrayList() {
+ return new ArrayList<E>();
+ }
+
+ /**
+ * Creates an {@code ArrayList} instance containing the given elements.
+ *
+ * <p><b>Note:</b> if you need an immutable List, use {@link ImmutableList}
+ * instead.
+ *
+ * <p><b>Note:</b> due to a bug in javac 1.5.0_06, we cannot support the
+ * following:
+ *
+ * <p>{@code List<Base> list = Lists.newArrayList(sub1, sub2);}
+ *
+ * <p>where {@code sub1} and {@code sub2} are references to subtypes of {@code
+ * Base}, not of {@code Base} itself. To get around this, you must use:
+ *
+ * <p>{@code List<Base> list = Lists.<Base>newArrayList(sub1, sub2);}
+ *
+ * @param elements the elements that the list should contain, in order
+ * @return a newly-created {@code ArrayList} containing those elements
+ */
+ public static <E> ArrayList<E> newArrayList(E... elements) {
+ // Avoid integer overflow when a large array is passed in
+ int capacity = computeArrayListCapacity(elements.length);
+ ArrayList<E> list = new ArrayList<E>(capacity);
+ Collections.addAll(list, elements);
+ return list;
+ }
+
+ static int computeArrayListCapacity(int arraySize) {
+ return (int) Math.min(5L + arraySize + (arraySize / 10), Integer.MAX_VALUE);
+ }
+
+ /**
+ * Creates an {@code ArrayList} instance containing the given elements.
+ *
+ * @param elements the elements that the list should contain, in order
+ * @return a newly-created {@code ArrayList} containing those elements
+ */
+ public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
+ // Let ArrayList's sizing logic work, if possible
+ if (elements instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<? extends E> collection = (Collection<? extends E>) elements;
+ return new ArrayList<E>(collection);
+ } else {
+ return newArrayList(elements.iterator());
+ }
+ }
+
+ /**
+ * Creates an {@code ArrayList} instance containing the given elements.
+ *
+ * @param elements the elements that the list should contain, in order
+ * @return a newly-created {@code ArrayList} containing those elements
+ */
+ public static <E> ArrayList<E> newArrayList(Iterator<? extends E> elements) {
+ ArrayList<E> list = newArrayList();
+ while (elements.hasNext()) {
+ list.add(elements.next());
+ }
+ return list;
+ }
+
+ /**
+ * Creates an {@code ArrayList} instance with the given expected size.
+ *
+ * @param expectedSize the expected size of the list
+ * @return a newly-created, initially empty {@code ArrayList} with enough
+ * capacity for the given expected size
+ * @throws IllegalArgumentException if the specified expected size is negative
+ */
+ public static <E> ArrayList<E> newArrayListWithExpectedSize(int expectedSize)
+ {
+ return new ArrayList<E>(computeArrayListCapacity(expectedSize));
+ }
+
+ // LinkedList
+
+ /**
+ * Creates an empty {@code LinkedList} instance.
+ *
+ * <p><b>Note:</b> if you need an immutable empty {@link List}, use
+ * {@link Collections#emptyList} instead.
+ *
+ * @return a newly-created, initially-empty {@code LinkedList}
+ */
+ public static <E> LinkedList<E> newLinkedList() {
+ return new LinkedList<E>();
+ }
+
+ /**
+ * Creates a {@code LinkedList} instance containing the given elements.
+ *
+ * @param elements the elements that the list should contain, in order
+ * @return a newly-created {@code LinkedList} containing those elements
+ */
+ public static <E> LinkedList<E> newLinkedList(
+ Iterable<? extends E> elements) {
+ return newLinkedList(elements.iterator());
+ }
+
+ /**
+ * Creates a {@code LinkedList} instance containing the given elements.
+ *
+ * @param elements the elements that the list should contain, in order
+ * @return a newly-created {@code LinkedList} containing those elements
+ */
+ private static <E> LinkedList<E> newLinkedList(
+ Iterator<? extends E> elements) {
+ LinkedList<E> list = newLinkedList();
+ while (elements.hasNext()) {
+ list.add(elements.next());
+ }
+ return list;
+ }
+
+ /**
+ * Returns a copy of the given iterable sorted by the natural ordering of its
+ * elements. The input is not modified. The returned list is modifiable,
+ * serializable, and implements {@link RandomAccess}.
+ *
+ * <p>Unlike {@link Sets#newTreeSet(Iterable)}, this method does not collapse
+ * equal elements, and the resulting collection does not maintain its own sort
+ * order.
+ *
+ * @param iterable the elements to be copied and sorted
+ * @return a new list containing the given elements in sorted order
+ * @throws ClassCastException if {@code iterable} contains elements that are
+ * not mutually comparable
+ */
+ @SuppressWarnings("unchecked")
+ public static <E extends Comparable> List<E> sortedCopy(Iterable<E> iterable)
+ {
+ List<E> list = Lists.newArrayList(iterable);
+ Collections.sort(list);
+ return list;
+ }
+
+ /**
+ * Returns a copy of the given iterable sorted by an explicit comparator. The
+ * input is not modified. The returned list is modifiable, serializable, and
+ * implements {@link RandomAccess}.
+ *
+ * <p>Unlike {@link Sets#newTreeSet(Comparator, Iterable)}, this method does
+ * not collapse elements that the comparator treats as equal, and the
+ * resulting collection does not maintain its own sort order.
+ *
+ * @param iterable the elements to be copied and sorted
+ * @param comparator a comparator capable of sorting the given elements
+ * @return a new list containing the given elements in sorted order
+ */
+ public static <E> List<E> sortedCopy(
+ Iterable<E> iterable, Comparator<? super E> comparator) {
+ List<E> list = Lists.newArrayList(iterable);
+ Collections.sort(list, checkNotNull(comparator));
+ return list;
+ }
+
+ /**
+ * Returns an unmodifiable list containing the specified first element and
+ * backed by the specified array of additional elements. Changes to the {@code
+ * rest} array will be reflected in the returned list. Unlike {@link
+ * Arrays#asList}, the returned list is unmodifiable.
+ *
+ * <p>This is useful when a varargs method needs to use a signature such as
+ * {@code (Foo firstFoo, Foo... moreFoos)}, in order to avoid overload
+ * ambiguity or to enforce a minimum argument count.
+ *
+ * <p>The returned list is serializable and implements {@link RandomAccess}.
+ *
+ * @param first the first element
+ * @param rest an array of additional elements, possibly empty
+ * @return an unmodifiable list containing the specified elements
+ */
+ public static <E> List<E> asList(@Nullable E first, E[] rest) {
+ return new OnePlusArrayList<E>(first, rest);
+ }
+
+ /** @see Lists#asList(Object,Object[]) */
+ private static class OnePlusArrayList<E> extends AbstractList<E>
+ implements Serializable, RandomAccess {
+ final E first;
+ final E[] rest;
+
+ OnePlusArrayList(@Nullable E first, E[] rest) {
+ this.first = first;
+ this.rest = checkNotNull(rest);
+ }
+ @Override public int size() {
+ return rest.length + 1;
+ }
+ @Override public E get(int index) {
+ return (index == 0) ? first : rest[index - 1]; // allow IOOBE to throw
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns an unmodifiable list containing the specified first and second
+ * element, and backed by the specified array of additional elements. Changes
+ * to the {@code rest} array will be reflected in the returned list. Unlike
+ * {@link Arrays#asList}, the returned list is unmodifiable.
+ *
+ * <p>This is useful when a varargs method needs to use a signature such as
+ * {@code (Foo firstFoo, Foo secondFoo, Foo... moreFoos)}, in order to avoid
+ * overload ambiguity or to enforce a minimum argument count.
+ *
+ * <p>The returned list is serializable and implements {@link RandomAccess}.
+ *
+ * @param first the first element
+ * @param second the second element
+ * @param rest an array of additional elements, possibly empty
+ * @return an unmodifiable list containing the specified elements
+ */
+ public static <E> List<E> asList(
+ @Nullable E first, @Nullable E second, E[] rest) {
+ return new TwoPlusArrayList<E>(first, second, rest);
+ }
+
+ /** @see Lists#asList(Object,Object,Object[]) */
+ private static class TwoPlusArrayList<E> extends AbstractList<E>
+ implements Serializable, RandomAccess {
+ final E first;
+ final E second;
+ final E[] rest;
+
+ TwoPlusArrayList(@Nullable E first, @Nullable E second, E[] rest) {
+ this.first = first;
+ this.second = second;
+ this.rest = checkNotNull(rest);
+ }
+ @Override public int size() {
+ return rest.length + 2;
+ }
+ @Override public E get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ default:
+ return rest[index - 2]; // allow IOOBE to throw
+ }
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a list that applies {@code function} to each element of {@code
+ * fromList}. The returned list is a transformed view of {@code fromList};
+ * changes to {@code fromList} will be reflected in the returned list and vice
+ * versa.
+ *
+ * <p>Since functions are not reversible, the transform is one-way and new
+ * items cannot be stored in the returned list. The {@code add},
+ * {@code addAll} and {@code set} methods are unsupported in the returned
+ * list.
+ *
+ * <p>The function is applied lazily, invoked when needed. This is necessary
+ * for the returned list to be a view, but it means that the function will be
+ * applied many times for bulk operations like {@link List#contains} and
+ * {@link List#hashCode}. For this to perform well, {@code function} should be
+ * fast. To avoid lazy evaluation when the returned list doesn't need to be a
+ * view, copy the returned list into a new list of your choosing.
+ *
+ * <p>If {@code fromList} implements {@link RandomAccess}, so will the
+ * returned list. The returned list always implements {@link Serializable},
+ * but serialization will succeed only when {@code fromList} and
+ * {@code function} are serializable. The returned list is threadsafe if the
+ * supplied list and function are.
+ */
+ public static <F, T> List<T> transform(
+ List<F> fromList, Function<? super F, ? extends T> function) {
+ return (fromList instanceof RandomAccess)
+ ? new TransformingRandomAccessList<F, T>(fromList, function)
+ : new TransformingSequentialList<F, T>(fromList, function);
+ }
+
+ /**
+ * Implementation of a sequential transforming list.
+ *
+ * @see Lists#transform
+ */
+ private static class TransformingSequentialList<F, T>
+ extends AbstractSequentialList<T> implements Serializable {
+ final List<F> fromList;
+ final Function<? super F, ? extends T> function;
+
+ TransformingSequentialList(
+ List<F> fromList, Function<? super F, ? extends T> function) {
+ this.fromList = checkNotNull(fromList);
+ this.function = checkNotNull(function);
+ }
+ /**
+ * The default implementation inherited is based on iteration and removal of
+ * each element which can be overkill. That's why we forward this call
+ * directly to the backing list.
+ */
+ @Override public void clear() {
+ fromList.clear();
+ }
+ @Override public int size() {
+ return fromList.size();
+ }
+ @Override public ListIterator<T> listIterator(final int index) {
+ final ListIterator<F> delegate = fromList.listIterator(index);
+ return new ListIterator<T>() {
+ public void add(T e) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasNext() {
+ return delegate.hasNext();
+ }
+
+ public boolean hasPrevious() {
+ return delegate.hasPrevious();
+ }
+
+ public T next() {
+ return function.apply(delegate.next());
+ }
+
+ public int nextIndex() {
+ return delegate.nextIndex();
+ }
+
+ public T previous() {
+ return function.apply(delegate.previous());
+ }
+
+ public int previousIndex() {
+ return delegate.previousIndex();
+ }
+
+ public void remove() {
+ delegate.remove();
+ }
+
+ public void set(T e) {
+ throw new UnsupportedOperationException("not supported");
+ }
+ };
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return super.removeAll(checkNotNull(c));
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Implementation of a transforming random access list. We try to make as many
+ * of these methods pass-through to the source list as possible so that the
+ * performance characteristics of the source list and transformed list are
+ * similar.
+ *
+ * @see Lists#transform
+ */
+ private static class TransformingRandomAccessList<F, T>
+ extends AbstractList<T> implements RandomAccess, Serializable {
+ final List<F> fromList;
+ final Function<? super F, ? extends T> function;
+
+ TransformingRandomAccessList(
+ List<F> fromList, Function<? super F, ? extends T> function) {
+ this.fromList = checkNotNull(fromList);
+ this.function = checkNotNull(function);
+ }
+ @Override public void clear() {
+ fromList.clear();
+ }
+ @Override public T get(int index) {
+ return function.apply(fromList.get(index));
+ }
+ @Override public boolean isEmpty() {
+ return fromList.isEmpty();
+ }
+ @Override public T remove(int index) {
+ return function.apply(fromList.remove(index));
+ }
+ @Override public int size() {
+ return fromList.size();
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return super.removeAll(checkNotNull(c));
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private static class ImmutableArrayList<E> extends AbstractList<E>
+ implements RandomAccess, Serializable {
+ final E[] array;
+
+ /**
+ * @param array underlying array for this ImmutableArrayList. Note that the
+ * array is <b>not</b> cloned. The caller is responsible for ensuring
+ * that the array can't "escape".
+ */
+ ImmutableArrayList(E[] array) {
+ this.array = array;
+ }
+ @Override public E get(int index) {
+ return array[index];
+ }
+ @Override public int size() {
+ return array.length;
+ }
+
+ // optimizations
+
+ @Override public Object[] toArray() {
+ Object[] newArray = new Object[array.length];
+ System.arraycopy(array, 0, newArray, 0, array.length);
+ return newArray;
+ }
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraint.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraint.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraint.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+/**
+ * A constraint on the keys and values that may be added to a {@code Map} or
+ * {@code Multimap}. For example, {@link MapConstraints#NOT_NULL}, which
+ * prevents a map from including any null keys or values, could be implemented
+ * like this: <pre> {@code
+ *
+ * public void checkKeyValue(Object key, Object value) {
+ * if (key == null || value == null) {
+ * throw new NullPointerException();
+ * }
+ * }}</pre>
+ *
+ * In order to be effective, constraints should be deterministic; that is, they
+ * should not depend on state that can change (such as external state, random
+ * variables, and time) and should only depend on the value of the passed-in key
+ * and value. A non-deterministic constraint cannot reliably enforce that all
+ * the collection's elements meet the constraint, since the constraint is only
+ * enforced when elements are added.
+ *
+ * @author Mike Bostock
+ * @see MapConstraints
+ * @see Constraint
+ */
+public interface MapConstraint<K, V> {
+ /**
+ * Throws a suitable {@code RuntimeException} if the specified key or value is
+ * illegal. Typically this is either a {@link NullPointerException}, an
+ * {@link IllegalArgumentException}, or a {@link ClassCastException}, though
+ * an application-specific exception class may be used if appropriate.
+ */
+ void checkKeyValue(@Nullable K key, @Nullable V value);
+
+ /**
+ * Returns a brief human readable description of this constraint, such as
+ * "Not null".
+ */
+ String toString();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraints.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraints.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/MapConstraints.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Factory and utilities pertaining to the {@code MapConstraint} interface.
+ *
+ * @see Constraints
+ * @author Mike Bostock
+ */
+public final class MapConstraints {
+ private MapConstraints() {}
+
+ /**
+ * A constraint that verifies that neither the key nor the value is null. If
+ * either is null, a {@link NullPointerException} is thrown.
+ */
+ public static final MapConstraint<Object, Object> NOT_NULL =
+ NotNullMapConstraint.INSTANCE;
+
+ // enum singleton pattern
+ private enum NotNullMapConstraint implements MapConstraint<Object, Object> {
+ INSTANCE;
+
+ public void checkKeyValue(Object key, Object value) {
+ checkNotNull(key);
+ checkNotNull(value);
+ }
+
+ @Override public String toString() {
+ return "Not null";
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified map, using the specified
+ * constraint. Any operations that add new mappings will call the provided
+ * constraint. However, this method does not verify that existing mappings
+ * satisfy the constraint.
+ *
+ * <p>The returned map is not serializable.
+ *
+ * @param map the map to constrain
+ * @param constraint the constraint that validates added entries
+ * @return a constrained view of the specified map
+ */
+ public static <K, V> Map<K, V> constrainedMap(
+ Map<K, V> map, MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedMap<K, V>(map, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified multimap, using the specified
+ * constraint. Any operations that add new mappings will call the provided
+ * constraint. However, this method does not verify that existing mappings
+ * satisfy the constraint.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are not
+ * constrained.
+ * <p>The returned multimap is not serializable.
+ *
+ * @param multimap the multimap to constrain
+ * @param constraint the constraint that validates added entries
+ * @return a constrained view of the multimap
+ */
+ public static <K, V> Multimap<K, V> constrainedMultimap(
+ Multimap<K, V> multimap, MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedMultimap<K, V>(multimap, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified list multimap, using the
+ * specified constraint. Any operations that add new mappings will call the
+ * provided constraint. However, this method does not verify that existing
+ * mappings satisfy the constraint.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are not
+ * constrained.
+ *
+ * <p>The returned multimap is not serializable.
+ *
+ * @param multimap the multimap to constrain
+ * @param constraint the constraint that validates added entries
+ * @return a constrained view of the specified multimap
+ */
+ public static <K, V> ListMultimap<K, V> constrainedListMultimap(
+ ListMultimap<K, V> multimap,
+ MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedListMultimap<K, V>(multimap, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified set multimap, using the
+ * specified constraint. Any operations that add new mappings will call the
+ * provided constraint. However, this method does not verify that existing
+ * mappings satisfy the constraint.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are not
+ * constrained.
+ * <p>The returned multimap is not serializable.
+ *
+ * @param multimap the multimap to constrain
+ * @param constraint the constraint that validates added entries
+ * @return a constrained view of the specified multimap
+ */
+ public static <K, V> SetMultimap<K, V> constrainedSetMultimap(
+ SetMultimap<K, V> multimap,
+ MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedSetMultimap<K, V>(multimap, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified sorted-set multimap, using the
+ * specified constraint. Any operations that add new mappings will call the
+ * provided constraint. However, this method does not verify that existing
+ * mappings satisfy the constraint.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are not
+ * constrained.
+ * <p>The returned multimap is not serializable.
+ *
+ * @param multimap the multimap to constrain
+ * @param constraint the constraint that validates added entries
+ * @return a constrained view of the specified multimap
+ */
+ public static <K, V> SortedSetMultimap<K, V> constrainedSortedSetMultimap(
+ SortedSetMultimap<K, V> multimap,
+ MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedSortedSetMultimap<K, V>(multimap, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified entry, using the specified
+ * constraint. The {@link Entry#setValue} operation will be verified with the
+ * constraint.
+ *
+ * @param entry the entry to constrain
+ * @param constraint the constraint for the entry
+ * @return a constrained view of the specified entry
+ */
+ private static <K, V> Entry<K, V> constrainedEntry(
+ final Entry<K, V> entry,
+ final MapConstraint<? super K, ? super V> constraint) {
+ checkNotNull(entry);
+ checkNotNull(constraint);
+ return new ForwardingMapEntry<K, V>() {
+ @Override protected Entry<K, V> delegate() {
+ return entry;
+ }
+ @Override public V setValue(V value) {
+ constraint.checkKeyValue(getKey(), value);
+ return entry.setValue(value);
+ }
+ };
+ }
+
+ /**
+ * Returns a constrained view of the specified {@code asMap} entry, using the
+ * specified constraint. The {@link Entry#setValue} operation will be verified
+ * with the constraint, and the collection returned by {@link Entry#getValue}
+ * will be similarly constrained.
+ *
+ * @param entry the {@code asMap} entry to constrain
+ * @param constraint the constraint for the entry
+ * @return a constrained view of the specified entry
+ */
+ private static <K, V> Entry<K, Collection<V>> constrainedAsMapEntry(
+ final Entry<K, Collection<V>> entry,
+ final MapConstraint<? super K, ? super V> constraint) {
+ checkNotNull(entry);
+ checkNotNull(constraint);
+ return new ForwardingMapEntry<K, Collection<V>>() {
+ @Override protected Entry<K, Collection<V>> delegate() {
+ return entry;
+ }
+ @Override public Collection<V> getValue() {
+ return Constraints.constrainedTypePreservingCollection(
+ entry.getValue(), new Constraint<V>() {
+ public V checkElement(V value) {
+ constraint.checkKeyValue(getKey(), value);
+ return value;
+ }
+ });
+ }
+ };
+ }
+
+ /**
+ * Returns a constrained view of the specified set of {@code asMap} entries,
+ * using the specified constraint. The {@link Entry#setValue} operation will
+ * be verified with the constraint, and the collection returned by {@link
+ * Entry#getValue} will be similarly constrained. The {@code add} and {@code
+ * addAll} operations simply forward to the underlying set, which throws an
+ * {@link UnsupportedOperationException} per the multimap specification.
+ *
+ * @param entries the entries to constrain
+ * @param constraint the constraint for the entries
+ * @return a constrained view of the entries
+ */
+ private static <K, V> Set<Entry<K, Collection<V>>> constrainedAsMapEntries(
+ Set<Entry<K, Collection<V>>> entries,
+ MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedAsMapEntries<K, V>(entries, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified collection (or set) of entries,
+ * using the specified constraint. The {@link Entry#setValue} operation will
+ * be verified with the constraint, along with add operations on the returned
+ * collection. The {@code add} and {@code addAll} operations simply forward to
+ * the underlying collection, which throws an {@link
+ * UnsupportedOperationException} per the map and multimap specification.
+ *
+ * @param entries the entries to constrain
+ * @param constraint the constraint for the entries
+ * @return a constrained view of the specified entries
+ */
+ private static <K, V> Collection<Entry<K, V>> constrainedEntries(
+ Collection<Entry<K, V>> entries,
+ MapConstraint<? super K, ? super V> constraint) {
+ if (entries instanceof Set) {
+ return constrainedEntrySet((Set<Entry<K, V>>) entries, constraint);
+ }
+ return new ConstrainedEntries<K, V>(entries, constraint);
+ }
+
+ /**
+ * Returns a constrained view of the specified set of entries, using the
+ * specified constraint. The {@link Entry#setValue} operation will be verified
+ * with the constraint, along with add operations on the returned set. The
+ * {@code add} and {@code addAll} operations simply forward to the underlying
+ * set, which throws an {@link UnsupportedOperationException} per the map and
+ * multimap specification.
+ *
+ * <p>The returned multimap is not serializable.
+ *
+ * @param entries the entries to constrain
+ * @param constraint the constraint for the entries
+ * @return a constrained view of the specified entries
+ */
+ private static <K, V> Set<Entry<K, V>> constrainedEntrySet(
+ Set<Entry<K, V>> entries,
+ MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedEntrySet<K, V>(entries, constraint);
+ }
+
+ /** @see MapConstraints#constrainedMap */
+ static class ConstrainedMap<K, V> extends ForwardingMap<K, V> {
+ final Map<K, V> delegate;
+ final MapConstraint<? super K, ? super V> constraint;
+ private transient volatile Set<Entry<K, V>> entrySet;
+
+ ConstrainedMap(
+ Map<K, V> delegate, MapConstraint<? super K, ? super V> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+ @Override protected Map<K, V> delegate() {
+ return delegate;
+ }
+ @Override public Set<Entry<K, V>> entrySet() {
+ if (entrySet == null) {
+ entrySet = constrainedEntrySet(delegate.entrySet(), constraint);
+ }
+ return entrySet;
+ }
+ @Override public V put(K key, V value) {
+ constraint.checkKeyValue(key, value);
+ return delegate.put(key, value);
+ }
+ @Override public void putAll(Map<? extends K, ? extends V> map) {
+ delegate.putAll(checkMap(map, constraint));
+ }
+ }
+
+ /**
+ * Returns a constrained view of the specified bimap, using the specified
+ * constraint. Any operations that modify the bimap will have the associated
+ * keys and values verified with the constraint.
+ *
+ * <p>The returned bimap is not serializable.
+ *
+ * @param map the bimap to constrain
+ * @param constraint the constraint that validates added entries
+ * @return a constrained view of the specified bimap
+ */
+ public static <K, V> BiMap<K, V> constrainedBiMap(
+ BiMap<K, V> map, MapConstraint<? super K, ? super V> constraint) {
+ return new ConstrainedBiMap<K, V>(map, null, constraint);
+ }
+
+ /** @see MapConstraints#constrainedBiMap */
+ private static class ConstrainedBiMap<K, V> extends ConstrainedMap<K, V>
+ implements BiMap<K, V> {
+ transient volatile BiMap<V, K> inverse;
+
+ ConstrainedBiMap(BiMap<K, V> delegate, BiMap<V, K> inverse,
+ MapConstraint<? super K, ? super V> constraint) {
+ super(delegate, constraint);
+ this.inverse = inverse;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override protected BiMap<K, V> delegate() {
+ return (BiMap<K, V>) super.delegate();
+ }
+
+ public V forcePut(K key, V value) {
+ constraint.checkKeyValue(key, value);
+ return delegate().forcePut(key, value);
+ }
+
+ public BiMap<V, K> inverse() {
+ if (inverse == null) {
+ inverse = new ConstrainedBiMap<V, K>(delegate().inverse(), this,
+ new InverseConstraint<V, K>(constraint));
+ }
+ return inverse;
+ }
+
+ @Override public Set<V> values() {
+ return delegate().values();
+ }
+ }
+
+ /** @see MapConstraints#constrainedBiMap */
+ private static class InverseConstraint<K, V> implements MapConstraint<K, V> {
+ final MapConstraint<? super V, ? super K> constraint;
+
+ public InverseConstraint(MapConstraint<? super V, ? super K> constraint) {
+ this.constraint = checkNotNull(constraint);
+ }
+ public void checkKeyValue(K key, V value) {
+ constraint.checkKeyValue(value, key);
+ }
+ }
+
+ /** @see MapConstraints#constrainedMultimap */
+ private static class ConstrainedMultimap<K, V>
+ extends ForwardingMultimap<K, V> {
+ final MapConstraint<? super K, ? super V> constraint;
+ final Multimap<K, V> delegate;
+ transient volatile Collection<Entry<K, V>> entries;
+ transient volatile Map<K, Collection<V>> asMap;
+
+ public ConstrainedMultimap(Multimap<K, V> delegate,
+ MapConstraint<? super K, ? super V> constraint) {
+ this.delegate = checkNotNull(delegate);
+ this.constraint = checkNotNull(constraint);
+ }
+
+ @Override protected Multimap<K, V> delegate() {
+ return delegate;
+ }
+
+ @Override public Map<K, Collection<V>> asMap() {
+ if (asMap == null) {
+ final Map<K, Collection<V>> asMapDelegate = delegate.asMap();
+
+ asMap = new ForwardingMap<K, Collection<V>>() {
+ volatile Set<Entry<K, Collection<V>>> entrySet;
+ volatile Collection<Collection<V>> values;
+
+ @Override protected Map<K, Collection<V>> delegate() {
+ return asMapDelegate;
+ }
+
+ @Override public Set<Entry<K, Collection<V>>> entrySet() {
+ if (entrySet == null) {
+ entrySet = constrainedAsMapEntries(
+ asMapDelegate.entrySet(), constraint);
+ }
+ return entrySet;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override public Collection<V> get(Object key) {
+ try {
+ Collection<V> collection = ConstrainedMultimap.this.get((K) key);
+ return collection.isEmpty() ? null : collection;
+ } catch (ClassCastException e) {
+ return null; // key wasn't a K
+ }
+ }
+
+ @Override public Collection<Collection<V>> values() {
+ if (values == null) {
+ values = new ConstrainedAsMapValues<K, V>(
+ delegate().values(), entrySet());
+ }
+ return values;
+ }
+
+ @Override public boolean containsValue(Object o) {
+ return values().contains(o);
+ }
+ };
+ }
+ return asMap;
+ }
+
+ @Override public Collection<Entry<K, V>> entries() {
+ if (entries == null) {
+ entries = constrainedEntries(delegate.entries(), constraint);
+ }
+ return entries;
+ }
+
+ @Override public Collection<V> get(final K key) {
+ return Constraints.constrainedTypePreservingCollection(
+ delegate.get(key), new Constraint<V>() {
+ public V checkElement(V value) {
+ constraint.checkKeyValue(key, value);
+ return value;
+ }
+ });
+ }
+
+ @Override public boolean put(K key, V value) {
+ constraint.checkKeyValue(key, value);
+ return delegate.put(key, value);
+ }
+
+ @Override public boolean putAll(K key, Iterable<? extends V> values) {
+ return delegate.putAll(key, checkValues(key, values, constraint));
+ }
+
+ @Override public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ return delegate.putAll(checkMultimap(multimap, constraint));
+ }
+
+ @Override public Collection<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ return delegate.replaceValues(key, checkValues(key, values, constraint));
+ }
+ }
+
+ /** @see ConstrainedMultimap#asMap */
+ private static class ConstrainedAsMapValues<K, V>
+ extends ForwardingCollection<Collection<V>> {
+ final Collection<Collection<V>> delegate;
+ final Set<Entry<K, Collection<V>>> entrySet;
+
+ /**
+ * @param entrySet map entries, linking each key with its corresponding
+ * values, that already enforce the constraint
+ */
+ ConstrainedAsMapValues(Collection<Collection<V>> delegate,
+ Set<Entry<K, Collection<V>>> entrySet) {
+ this.delegate = delegate;
+ this.entrySet = entrySet;
+ }
+ @Override protected Collection<Collection<V>> delegate() {
+ return delegate;
+ }
+
+ @Override public Iterator<Collection<V>> iterator() {
+ final Iterator<Entry<K, Collection<V>>> iterator = entrySet.iterator();
+ return new Iterator<Collection<V>>() {
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ public Collection<V> next() {
+ return iterator.next().getValue();
+ }
+ public void remove() {
+ iterator.remove();
+ }
+ };
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+ @Override public boolean contains(Object o) {
+ return Iterators.contains(iterator(), o);
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+ @Override public boolean remove(Object o) {
+ return Iterables.remove(this, o);
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+ }
+
+ /** @see MapConstraints#constrainedEntries */
+ private static class ConstrainedEntries<K, V>
+ extends ForwardingCollection<Entry<K, V>> {
+ final MapConstraint<? super K, ? super V> constraint;
+ final Collection<Entry<K, V>> entries;
+
+ ConstrainedEntries(Collection<Entry<K, V>> entries,
+ MapConstraint<? super K, ? super V> constraint) {
+ this.entries = entries;
+ this.constraint = constraint;
+ }
+ @Override protected Collection<Entry<K, V>> delegate() {
+ return entries;
+ }
+
+ @Override public Iterator<Entry<K, V>> iterator() {
+ final Iterator<Entry<K, V>> iterator = entries.iterator();
+ return new ForwardingIterator<Entry<K, V>>() {
+ @Override public Entry<K, V> next() {
+ return constrainedEntry(iterator.next(), constraint);
+ }
+ @Override protected Iterator<Entry<K, V>> delegate() {
+ return iterator;
+ }
+ };
+ }
+
+ // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+ @Override public boolean contains(Object o) {
+ return Maps.containsEntryImpl(delegate(), o);
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+ @Override public boolean remove(Object o) {
+ return Maps.removeEntryImpl(delegate(), o);
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+ }
+
+ /** @see MapConstraints#constrainedEntrySet */
+ static class ConstrainedEntrySet<K, V>
+ extends ConstrainedEntries<K, V> implements Set<Entry<K, V>> {
+ ConstrainedEntrySet(Set<Entry<K, V>> entries,
+ MapConstraint<? super K, ? super V> constraint) {
+ super(entries, constraint);
+ }
+
+ // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
+
+ @Override public boolean equals(Object o) {
+ return Sets.equalsImpl(this, o);
+ }
+
+ @Override public int hashCode() {
+ return Sets.hashCodeImpl(this);
+ }
+ }
+
+ /** @see MapConstraints#constrainedAsMapEntries */
+ static class ConstrainedAsMapEntries<K, V>
+ extends ForwardingSet<Entry<K, Collection<V>>> {
+ private final MapConstraint<? super K, ? super V> constraint;
+ private final Set<Entry<K, Collection<V>>> entries;
+
+ ConstrainedAsMapEntries(Set<Entry<K, Collection<V>>> entries,
+ MapConstraint<? super K, ? super V> constraint) {
+ this.entries = entries;
+ this.constraint = constraint;
+ }
+
+ @Override protected Set<Entry<K, Collection<V>>> delegate() {
+ return entries;
+ }
+
+ @Override public Iterator<Entry<K, Collection<V>>> iterator() {
+ final Iterator<Entry<K, Collection<V>>> iterator = entries.iterator();
+ return new ForwardingIterator<Entry<K, Collection<V>>>() {
+ @Override public Entry<K, Collection<V>> next() {
+ return constrainedAsMapEntry(iterator.next(), constraint);
+ }
+ @Override protected Iterator<Entry<K, Collection<V>>> delegate() {
+ return iterator;
+ }
+ };
+ }
+
+ // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+
+ @Override public boolean contains(Object o) {
+ return Maps.containsEntryImpl(delegate(), o);
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+
+ @Override public boolean equals(Object o) {
+ return Sets.equalsImpl(this, o);
+ }
+
+ @Override public int hashCode() {
+ return Sets.hashCodeImpl(this);
+ }
+
+ @Override public boolean remove(Object o) {
+ return Maps.removeEntryImpl(delegate(), o);
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+ }
+
+ private static class ConstrainedListMultimap<K, V>
+ extends ConstrainedMultimap<K, V> implements ListMultimap<K, V> {
+ ConstrainedListMultimap(ListMultimap<K, V> delegate,
+ MapConstraint<? super K, ? super V> constraint) {
+ super(delegate, constraint);
+ }
+ @Override public List<V> get(K key) {
+ return (List<V>) super.get(key);
+ }
+ @Override public List<V> removeAll(Object key) {
+ return (List<V>) super.removeAll(key);
+ }
+ @Override public List<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ return (List<V>) super.replaceValues(key, values);
+ }
+ }
+
+ private static class ConstrainedSetMultimap<K, V>
+ extends ConstrainedMultimap<K, V> implements SetMultimap<K, V> {
+ ConstrainedSetMultimap(SetMultimap<K, V> delegate,
+ MapConstraint<? super K, ? super V> constraint) {
+ super(delegate, constraint);
+ }
+ @Override public Set<V> get(K key) {
+ return (Set<V>) super.get(key);
+ }
+ @Override public Set<Map.Entry<K, V>> entries() {
+ return (Set<Map.Entry<K, V>>) super.entries();
+ }
+ @Override public Set<V> removeAll(Object key) {
+ return (Set<V>) super.removeAll(key);
+ }
+ @Override public Set<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ return (Set<V>) super.replaceValues(key, values);
+ }
+ }
+
+ private static class ConstrainedSortedSetMultimap<K, V>
+ extends ConstrainedSetMultimap<K, V> implements SortedSetMultimap<K, V> {
+ ConstrainedSortedSetMultimap(SortedSetMultimap<K, V> delegate,
+ MapConstraint<? super K, ? super V> constraint) {
+ super(delegate, constraint);
+ }
+ @Override public SortedSet<V> get(K key) {
+ return (SortedSet<V>) super.get(key);
+ }
+ @Override public SortedSet<V> removeAll(Object key) {
+ return (SortedSet<V>) super.removeAll(key);
+ }
+ @Override public SortedSet<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ return (SortedSet<V>) super.replaceValues(key, values);
+ }
+ public Comparator<? super V> valueComparator() {
+ return ((SortedSetMultimap<K, V>) delegate()).valueComparator();
+ }
+ }
+
+ private static <K, V> Collection<V> checkValues(K key,
+ Iterable<? extends V> values,
+ MapConstraint<? super K, ? super V> constraint) {
+ Collection<V> copy = Lists.newArrayList(values);
+ for (V value : copy) {
+ constraint.checkKeyValue(key, value);
+ }
+ return copy;
+ }
+
+ private static <K, V> Map<K, V> checkMap(Map<? extends K, ? extends V> map,
+ MapConstraint<? super K, ? super V> constraint) {
+ Map<K, V> copy = new LinkedHashMap<K, V>(map);
+ for (Entry<K, V> entry : copy.entrySet()) {
+ constraint.checkKeyValue(entry.getKey(), entry.getValue());
+ }
+ return copy;
+ }
+
+ private static <K, V> Multimap<K, V> checkMultimap(
+ Multimap<? extends K, ? extends V> map,
+ MapConstraint<? super K, ? super V> constraint) {
+ Multimap<K, V> copy = new ArrayListMultimap<K, V>(map);
+ for (Entry<K, V> entry : copy.entries()) {
+ constraint.checkKeyValue(entry.getKey(), entry.getValue());
+ }
+ return copy;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Maps.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Maps.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Maps.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Function;
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Objects;
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import org.richfaces.collections.collect.MapConstraints.ConstrainedMap;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumMap;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Static utility methods pertaining to {@link Map} instances. Also see this
+ * class's counterparts {@link Lists} and {@link Sets}.
+ *
+ * @author Kevin Bourrillion
+ * @author Mike Bostock
+ */
+public final class Maps {
+ private Maps() {}
+
+ /**
+ * Creates a {@code HashMap} instance.
+ *
+ * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link
+ * #newEnumMap} instead.
+ *
+ * <p><b>Note:</b> if you don't actually need the resulting map to be mutable,
+ * use {@link Collections#emptyMap} instead.
+ *
+ * @return a newly-created, initially-empty {@code HashMap}
+ */
+ public static <K, V> HashMap<K, V> newHashMap() {
+ return new HashMap<K, V>();
+ }
+
+ /**
+ * Creates a {@code HashMap} instance with enough capacity to hold the
+ * specified number of elements without rehashing.
+ *
+ * @param expectedSize the expected size
+ * @return a newly-created {@code HashMap}, initially empty, with enough
+ * capacity to hold {@code expectedSize} elements without rehashing
+ * @throws IllegalArgumentException if {@code expectedSize} is negative
+ */
+ public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(
+ int expectedSize) {
+ /*
+ * The HashMap is constructed with an initialCapacity that's greater than
+ * expectedSize. The larger value is necessary because HashMap resizes
+ * its internal array if the map size exceeds loadFactor * initialCapacity.
+ */
+ return new HashMap<K, V>(capacity(expectedSize));
+ }
+
+ /**
+ * Returns an appropriate value for the "capacity" (in reality, "minimum
+ * table size") parameter of a {@link HashMap} constructor, such that the
+ * resulting table will be between 25% and 50% full when it contains
+ * {@code expectedSize} entries.
+ *
+ * @throws IllegalArgumentException if {@code expectedSize} is negative
+ */
+ static int capacity(int expectedSize) {
+ checkArgument(expectedSize >= 0);
+ return Math.max(expectedSize * 2, 16);
+ }
+
+ /**
+ * Creates a {@code HashMap} instance with the same mappings as the specified
+ * map.
+ *
+ * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link
+ * #newEnumMap} instead.
+ *
+ * @param map the mappings to be placed in the new map
+ * @return a newly-created {@code HashMap} initialized with the mappings from
+ * {@code map}
+ */
+ public static <K, V> HashMap<K, V> newHashMap(
+ Map<? extends K, ? extends V> map) {
+ return new HashMap<K, V>(map);
+ }
+
+ /**
+ * Creates an insertion-ordered {@code LinkedHashMap} instance.
+ *
+ * @return a newly-created, initially-empty {@code LinkedHashMap}
+ */
+ public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
+ return new LinkedHashMap<K, V>();
+ }
+
+ /**
+ * Creates an insertion-ordered {@code LinkedHashMap} instance with the same
+ * mappings as the specified map.
+ *
+ * @param map the mappings to be placed in the new map
+ * @return a newly-created, {@code LinkedHashMap} initialized with the
+ * mappings from {@code map}
+ */
+ public static <K, V> LinkedHashMap<K, V>
+ newLinkedHashMap(Map<? extends K, ? extends V> map) {
+ return new LinkedHashMap<K, V>(map);
+ }
+
+ /**
+ * Creates a {@code ConcurrentHashMap} instance.
+ *
+ * @return a newly-created, initially-empty {@code ConcurrentHashMap}
+ */
+ public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap() {
+ return new ConcurrentHashMap<K, V>();
+ }
+
+ /**
+ * Creates a {@code TreeMap} instance using the natural ordering of its
+ * elements.
+ *
+ * @return a newly-created, initially-empty {@code TreeMap}
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
+ return new TreeMap<K, V>();
+ }
+
+ /**
+ * Creates a {@code TreeMap} instance using the given comparator.
+ *
+ * @param comparator the comparator to sort the keys with
+ * @return a newly-created, initially-empty {@code TreeMap}
+ */
+ public static <C, K extends C, V> TreeMap<K, V> newTreeMap(
+ @Nullable Comparator<C> comparator) {
+ // Ideally, the extra type parameter "C" shouldn't be necessary. It is a
+ // work-around of a compiler type inference quirk that prevents the
+ // following code from being compiled:
+ // Comparator<Class<?>> comparator = null;
+ // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator);
+ return new TreeMap<K, V>(comparator);
+ }
+
+ /**
+ * Creates an {@code EnumMap} instance.
+ *
+ * @param type the key type for this map
+ * @return a newly-created, initially-empty {@code EnumMap}
+ */
+ public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) {
+ return new EnumMap<K, V>(type);
+ }
+
+ /**
+ * Creates an {@code IdentityHashMap} instance.
+ *
+ * @return a newly-created, initially-empty {@code IdentityHashMap}
+ */
+ public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
+ return new IdentityHashMap<K, V>();
+ }
+
+ /**
+ * Returns {@code true} if {@code map} contains an entry mapping {@code key}
+ * to {@code value}. If you are not concerned with null-safety you can simply
+ * use {@code map.get(key).equals(value)}.
+ */
+ public static boolean containsEntry(
+ Map<?, ?> map, @Nullable Object key, @Nullable Object value) {
+ Object valueForKey = map.get(key);
+ return (valueForKey == null)
+ ? value == null && map.containsKey(key)
+ : valueForKey.equals(value);
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) bimap backed by the specified bimap.
+ * In order to guarantee serial access, it is critical that <b>all</b> access
+ * to the backing bimap is accomplished through the returned bimap.
+ *
+ * <p>It is imperative that the user manually synchronize on the returned map
+ * when accessing any of its collection views:
+ *
+ * <pre> Bimap<K,V> m = Maps.synchronizedBiMap(
+ * new HashBiMap<K,V>());
+ * ...
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (m) { // Synchronizing on m, not s!
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param bimap the bimap to be wrapped in a synchronized view
+ * @return a sychronized view of the specified bimap
+ */
+ public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
+ return Synchronized.biMap(bimap, null);
+ }
+
+ /**
+ * Returns an immutable map for which the {@link Map#values} are the given
+ * elements in the given order, and each key is the product of invoking a
+ * supplied function on its corresponding value.
+ *
+ * @param values the values to use when constructing the {@code Map}
+ * @param keyFunction the function used to produce the key for each value
+ * @return a map mapping the result of evaluating the function {@code
+ * keyFunction} on each value in the input collection to that value
+ * @throws IllegalArgumentException if {@code keyFunction} produces the same
+ * key for more than one value in the input collection
+ * @throws NullPointerException if any elements of {@code values} is null, or
+ * if {@code keyFunction} produces {@code null} for any value
+ */
+ // TODO: consider returning a bimap, whose inverse view does lookups by
+ // invoking the function.
+ public static <K, V> ImmutableMap<K, V> uniqueIndex(
+ Iterable<V> values, Function<? super V, K> keyFunction) {
+ checkNotNull(keyFunction);
+ ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
+ for (V value : values) {
+ builder.put(keyFunction.apply(value), value);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Creates a {@code Map<String, String>} from a {@code Properties} instance.
+ * Properties normally derive from {@code Map<Object, Object>}, but they
+ * typically contain strings, which is awkward. This method lets you get a
+ * plain-old-{@code Map} out of a {@code Properties}. The returned map won't
+ * include any null keys or values. The returned map is modifiable and
+ * serializable.
+ *
+ * @param properties a {@code Properties} object to be converted
+ * @return a map containing all the entries in {@code properties}
+ */
+ public static Map<String, String> fromProperties(Properties properties) {
+ Map<String, String> ret = newHashMapWithExpectedSize(properties.size());
+ for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {
+ Object k = e.nextElement();
+ /*
+ * It is unlikely that a 'null' could be inserted into a Properties, but
+ * possible in a derived class.
+ */
+ String key = (k != null) ? k.toString() : null;
+ ret.put(key, properties.getProperty(key));
+ }
+ return ret;
+ }
+
+ /**
+ * Returns an immutable map entry with the specified key and value. The {@link
+ * Entry#setValue} operation throws an {@link UnsupportedOperationException}.
+ *
+ * <p>The returned entry is serializable.
+ *
+ * @param key the key to be associated with the returned entry
+ * @param value the value to be associated with the returned entry
+ */
+ public static <K, V> Entry<K, V> immutableEntry(
+ @Nullable final K key, @Nullable final V value) {
+ return new ImmutableEntry<K, V>(key, value);
+ }
+
+ /** @see Maps#immutableEntry(Object,Object) */
+ private static class ImmutableEntry<K, V> extends AbstractMapEntry<K, V>
+ implements Serializable {
+ final K key;
+ final V value;
+
+ ImmutableEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+ @Override public K getKey() {
+ return key;
+ }
+ @Override public V getValue() {
+ return value;
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified set of entries. The {@link
+ * Entry#setValue} operation throws an {@link UnsupportedOperationException},
+ * as do any operations that would modify the returned set.
+ *
+ * @param entrySet the entries for which to return an unmodifiable view
+ * @return an unmodifiable view of the entries
+ */
+ static <K, V> Set<Entry<K, V>> unmodifiableEntrySet(
+ final Set<Entry<K, V>> entrySet) {
+ return new UnmodifiableEntrySet<K, V>(Collections.unmodifiableSet(
+ entrySet));
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified map entry. The {@link
+ * Entry#setValue} operation throws an {@link UnsupportedOperationException}.
+ * This also has the side-effect of redefining {@code equals} to comply with
+ * the Entry contract, to avoid a possible nefarious implementation of
+ * equals.
+ *
+ * @param entry the entry for which to return an unmodifiable view
+ * @return an unmodifiable view of the entry
+ */
+ private static <K, V> Entry<K, V> unmodifiableEntry(final Entry<K, V> entry) {
+ checkNotNull(entry);
+ return new AbstractMapEntry<K, V>() {
+ @Override public K getKey() {
+ return entry.getKey();
+ }
+ @Override public V getValue() {
+ return entry.getValue();
+ }
+ };
+ }
+
+ /** @see Multimaps#unmodifiableEntries */
+ static class UnmodifiableEntries<K, V>
+ extends ForwardingCollection<Entry<K, V>> {
+ private final Collection<Entry<K, V>> entries;
+
+ UnmodifiableEntries(Collection<Entry<K, V>> entries) {
+ this.entries = entries;
+ }
+
+ @Override protected Collection<Entry<K, V>> delegate() {
+ return entries;
+ }
+
+ @Override public Iterator<Entry<K, V>> iterator() {
+ final Iterator<Entry<K, V>> delegate = super.iterator();
+ return new ForwardingIterator<Entry<K, V>>() {
+ @Override public Entry<K, V> next() {
+ return unmodifiableEntry(super.next());
+ }
+ @Override protected Iterator<Entry<K, V>> delegate() {
+ return delegate;
+ }
+ };
+ }
+
+ // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+
+ @Override public boolean contains(Object o) {
+ return containsEntryImpl(delegate(), o);
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+ }
+
+ /** @see Maps#unmodifiableEntrySet(Set) */
+ static class UnmodifiableEntrySet<K, V>
+ extends UnmodifiableEntries<K, V>
+ implements Set<Entry<K, V>> {
+ UnmodifiableEntrySet(Set<Entry<K, V>> entries) {
+ super(entries);
+ }
+
+ // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
+
+ @Override public boolean equals(Object o) {
+ return Sets.equalsImpl(this, o);
+ }
+
+ @Override public int hashCode() {
+ return Sets.hashCodeImpl(this);
+ }
+ }
+
+ /**
+ * Returns a new empty {@code HashBiMap} with the default initial capacity
+ * (16).
+ */
+ public static <K, V> HashBiMap<K, V> newHashBiMap() {
+ return new HashBiMap<K, V>();
+ }
+
+ /**
+ * Returns a new empty {@code EnumHashBiMap} using the specified key type.
+ *
+ * @param keyType the key type
+ */
+ public static <K extends Enum<K>, V> EnumHashBiMap<K, V> newEnumHashBiMap(
+ Class<K> keyType) {
+ return new EnumHashBiMap<K, V>(keyType);
+ }
+
+ /**
+ * Returns a new empty {@code EnumBiMap} using the specified key and value
+ * types.
+ *
+ * @param keyType the key type
+ * @param valueType the value type
+ */
+ public static <K extends Enum<K>, V extends Enum<V>> EnumBiMap<K, V>
+ newEnumBiMap(Class<K> keyType, Class<V> valueType) {
+ return new EnumBiMap<K, V>(keyType, valueType);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified bimap. This method allows
+ * modules to provide users with "read-only" access to internal bimaps. Query
+ * operations on the returned bimap "read through" to the specified bimap, and
+ * attemps to modify the returned map, whether direct or via its collection
+ * views, result in an {@code UnsupportedOperationException}.
+ *
+ * <p>The returned bimap will be serializable if the specified bimap is
+ * serializable.
+ *
+ * @param bimap the bimap for which an unmodifiable view is to be returned
+ * @return an unmodifiable view of the specified bimap
+ */
+ public static <K, V> BiMap<K, V> unmodifiableBiMap(BiMap<K, V> bimap) {
+ return new UnmodifiableBiMap<K, V>(bimap, null);
+ }
+
+ /** @see Maps#unmodifiableBiMap(BiMap) */
+ private static class UnmodifiableBiMap<K, V> extends ForwardingMap<K, V>
+ implements BiMap<K, V>, Serializable {
+ final Map<K, V> unmodifiableMap;
+ final BiMap<K, V> delegate;
+ transient BiMap<V, K> inverse;
+ transient Set<V> values;
+
+ UnmodifiableBiMap(BiMap<K, V> delegate, BiMap<V, K> inverse) {
+ unmodifiableMap = Collections.unmodifiableMap(delegate);
+ this.delegate = delegate;
+ this.inverse = inverse;
+ }
+ @Override protected Map<K, V> delegate() {
+ return unmodifiableMap;
+ }
+ public V forcePut(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+ public BiMap<V, K> inverse() {
+ BiMap<V, K> result = inverse;
+ return (result == null)
+ ? inverse = new UnmodifiableBiMap<V, K>(delegate.inverse(), this)
+ : result;
+ }
+ @Override public Set<V> values() {
+ Set<V> result = values;
+ return (result == null)
+ ? values = Collections.unmodifiableSet(delegate.values())
+ : result;
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a new {@code ClassToInstanceMap} instance backed by a {@link
+ * HashMap} using the default initial capacity and load factor.
+ */
+ public static <B> ClassToInstanceMap<B> newClassToInstanceMap() {
+ return newClassToInstanceMap(new HashMap<Class<? extends B>, B>());
+ }
+
+ /**
+ * Returns a new {@code ClassToInstanceMap} instance backed by a given empty
+ * {@code backingMap}. The caller surrenders control of the backing map, and
+ * thus should not allow any direct references to it to remain accessible.
+ */
+ public static <B> ClassToInstanceMap<B> newClassToInstanceMap(
+ Map<Class<? extends B>, B> backingMap) {
+ return new SimpleClassToInstanceMap<B>(backingMap);
+ }
+
+ private static final MapConstraint<Class<?>, Object> VALUE_CAN_BE_CAST_TO_KEY
+ = new MapConstraint<Class<?>, Object>() {
+ public void checkKeyValue(Class<?> key, Object value) {
+ wrap(key).cast(value);
+ }
+ };
+
+ private static class SimpleClassToInstanceMap<B> extends
+ ConstrainedMap<Class<? extends B>, B> implements ClassToInstanceMap<B> {
+ SimpleClassToInstanceMap(Map<Class<? extends B>, B> delegate) {
+ super(delegate, VALUE_CAN_BE_CAST_TO_KEY);
+ }
+ public <T extends B> T putInstance(Class<T> type, T value) {
+ B oldValue = put(type, value);
+ return wrap(type).cast(oldValue);
+ }
+ public <T extends B> T getInstance(Class<T> type) {
+ B value = get(type);
+ return wrap(type).cast(value);
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> Class<T> wrap(Class<T> c) {
+ return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c;
+ }
+
+ private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS
+ = new ImmutableMap.Builder<Class<?>, Class<?>>()
+ .put(boolean.class, Boolean.class)
+ .put(byte.class, Byte.class)
+ .put(char.class, Character.class)
+ .put(double.class, Double.class)
+ .put(float.class, Float.class)
+ .put(int.class, Integer.class)
+ .put(long.class, Long.class)
+ .put(short.class, Short.class)
+ .put(void.class, Void.class)
+ .build();
+
+ /**
+ * Implements {@code Collection.contains} safely for forwarding collections of
+ * map entries. If {@code o} is an instance of {@code Map.Entry}, it is
+ * wrapped using {@link #unmodifiableEntry} to protect against a possible
+ * nefarious equals method.
+ *
+ * <p>Note that {@code c} is the backing (delegate) collection, rather than
+ * the forwarding collection.
+ *
+ * @param c the delegate (unwrapped) collection of map entries
+ * @param o the object that might be contained in {@code c}
+ * @return {@code true} if {@code c} contains {@code o}
+ */
+ static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) {
+ if (!(o instanceof Entry)) {
+ return false;
+ }
+ return c.contains(unmodifiableEntry((Entry<?, ?>) o));
+ }
+
+ /**
+ * Implements {@code Collection.remove} safely for forwarding collections of
+ * map entries. If {@code o} is an instance of {@code Map.Entry}, it is
+ * wrapped using {@link #unmodifiableEntry} to protect against a possible
+ * nefarious equals method.
+ *
+ * <p>Note that {@code c} is backing (delegate) collection, rather than the
+ * forwarding collection.
+ *
+ * @param c the delegate (unwrapped) collection of map entries
+ * @param o the object to remove from {@code c}
+ * @return {@code true} if {@code c} was changed
+ */
+ static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) {
+ if (!(o instanceof Entry)) {
+ return false;
+ }
+ return c.remove(unmodifiableEntry((Entry<?, ?>) o));
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A collection similar to a {@code Map}, but which may associate multiple
+ * values with a single key. If you call {@link #put} twice, with the same key
+ * but different values, the multimap contains mappings from the key to both
+ * values.
+ *
+ * <p>The methods {@link #get}, {@link #keySet}, {@link #keys}, {@link #values},
+ * {@link #entries}, and {@link #asMap} return collections that are views of the
+ * multimap. If the multimap is modifiable, updating it can change the contents
+ * of those collections, and updating the collections will change the multimap.
+ * In contrast, {@link #replaceValues} and {@link #removeAll} return collections
+ * that are independent of subsequent multimap changes.
+ *
+ * <p>Depending on the implementation, a multimap may or may not allow duplicate
+ * key-value pairs. In other words, the multimap contents after adding the same
+ * key and value twice varies between implementations. In multimaps allowing
+ * duplicates, the multimap will contain two mappings, and {@code get} will
+ * return a collection that includes the value twice. In multimaps not
+ * supporting duplicates, the multimap will contain a single mapping from the
+ * key to the value, and {@code get} will return a collection that includes the
+ * value once.
+ *
+ * <p>All methods that alter the multimap are optional, and the views returned
+ * by the multimap may or may not be modifiable. When modification isn't
+ * supported, those methods will throw an {@link UnsupportedOperationException}.
+ *
+ * @author Jared Levy
+ * @param <K> the type of keys maintained by this multimap
+ * @param <V> the type of mapped values
+ */
+public interface Multimap<K, V> {
+ // Query Operations
+
+ /** Returns the number of key-value pairs in the multimap. */
+ int size();
+
+ /** Returns {@code true} if the multimap contains no key-value pairs. */
+ boolean isEmpty();
+
+ /**
+ * Returns {@code true} if the multimap contains any values for the specified
+ * key.
+ *
+ * @param key key to search for in multimap
+ */
+ boolean containsKey(@Nullable Object key);
+
+ /**
+ * Returns {@code true} if the multimap contains the specified value for any
+ * key.
+ *
+ * @param value value to search for in multimap
+ */
+ boolean containsValue(@Nullable Object value);
+
+ /**
+ * Returns {@code true} if the multimap contains the specified key-value pair.
+ *
+ * @param key key to search for in multimap
+ * @param value value to search for in multimap
+ */
+ boolean containsEntry(@Nullable Object key, @Nullable Object value);
+
+ // Modification Operations
+
+ /**
+ * Stores a key-value pair in the multimap.
+ *
+ * <p>Some multimap implementations allow duplicate key-value pairs, in which
+ * case {@code put} always adds a new key-value pair and increases the
+ * multimap size by 1. Other implementations prohibit duplicates, and storing
+ * a key-value pair that's already in the multimap has no effect.
+ *
+ * @param key key to store in the multimap
+ * @param value value to store in the multimap
+ * @return {@code true} if the method increased the size of the multimap, or
+ * {@code false} if the multimap already contained the key-value pair and
+ * doesn't allow duplicates
+ */
+ boolean put(K key, V value);
+
+ /**
+ * Removes a key-value pair from the multimap.
+ *
+ * @param key key of entry to remove from the multimap
+ * @param value value of entry to remove the multimap
+ * @return {@code true} if the multimap changed
+ */
+ boolean remove(@Nullable Object key, @Nullable Object value);
+
+ // Bulk Operations
+
+ /**
+ * Stores a collection of values with the same key.
+ *
+ * @param key key to store in the multimap
+ * @param values values to store in the multimap
+ * @return {@code true} if the multimap changed
+ */
+ boolean putAll(@Nullable K key, Iterable<? extends V> values);
+
+ /**
+ * Copies all of another multimap's key-value pairs into this multimap. The
+ * order in which the mappings are added is determined by
+ * {@code multimap.entries()}.
+ *
+ * @param multimap mappings to store in this multimap
+ * @return {@code true} if the multimap changed
+ */
+ boolean putAll(Multimap<? extends K, ? extends V> multimap);
+
+ /**
+ * Stores a collection of values with the same key, replacing any existing
+ * values for that key.
+ *
+ * @param key key to store in the multimap
+ * @param values values to store in the multimap
+ * @return the collection of replaced values, or an empty collection if no
+ * values were previously associated with the key. The collection
+ * <i>may</i> be modifiable, but updating it will have no effect on the
+ * multimap.
+ */
+ Collection<V> replaceValues(K key, Iterable<? extends V> values);
+
+ /**
+ * Removes all values associated with a given key.
+ *
+ * @param key key of entries to remove from the multimap
+ * @return the collection of removed values, or an empty collection if no
+ * values were associated with the provided key. The collection
+ * <i>may</i> be modifiable, but updating it will have no effect on the
+ * multimap.
+ */
+ Collection<V> removeAll(@Nullable Object key);
+
+ /**
+ * Removes all key-value pairs from the multimap.
+ */
+ void clear();
+
+ // Views
+
+ /**
+ * Returns a collection view of all values associated with a key. If no
+ * mappings in the multimap have the provided key, an empty collection is
+ * returned.
+ *
+ * <p>Changes to the returned collection will update the underlying multimap,
+ * and vice versa.
+ *
+ * @param key key to search for in multimap
+ * @return the collection of values that the key maps to
+ */
+ Collection<V> get(@Nullable K key);
+
+ /**
+ * Returns the set of all keys, each appearing once in the returned set.
+ * Changes to the returned set will update the underlying multimap, and vice
+ * versa.
+ *
+ * @return the collection of distinct keys
+ */
+ Set<K> keySet();
+
+ /**
+ * Returns a collection, which may contain duplicates, of all keys. The number
+ * of times of key appears in the returned multiset equals the number of
+ * mappings the key has in the multimap. Changes to the returned multiset will
+ * update the underlying multimap, and vice versa.
+ *
+ * @return a multiset with keys corresponding to the distinct keys of the
+ * multimap and frequencies corresponding to the number of values that
+ * each key maps to
+ */
+ Multiset<K> keys();
+
+ /**
+ * Returns a collection of all values in the multimap. Changes to the returned
+ * collection will update the underlying multimap, and vice versa.
+ *
+ * @return collection of values, which may include the same value multiple
+ * times if it occurs in multiple mappings
+ */
+ Collection<V> values();
+
+ /**
+ * Returns a collection of all key-value pairs. Changes to the returned
+ * collection will update the underlying multimap, and vice versa. The entries
+ * collection does not support the {@code add} or {@code addAll} operations.
+ *
+ * @return collection of map entries consisting of key-value pairs
+ */
+ Collection<Map.Entry<K, V>> entries();
+
+ /**
+ * Returns a map view that associates each key with the corresponding values
+ * in the multimap. Changes to the returned map, such as element removal,
+ * will update the underlying multimap. The map does not support
+ * {@code setValue()} on its entries, {@code put}, or {@code putAll}.
+ *
+ * <p>The collections returned by {@code asMap().get(Object)} have the same
+ * behavior as those returned by {@link #get}.
+ *
+ * @return a map view from a key to its collection of values
+ */
+ Map<K, Collection<V>> asMap();
+
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this multimap for equality. Two
+ * multimaps are equal when their map views, as returned by {@link #asMap},
+ * are also equal.
+ *
+ * <p>In general, two multimaps with identical key-value mappings may or may
+ * not be equal, depending on the implementation. For example, two
+ * {@link SetMultimap} instances with the same key-value mappings are equal,
+ * but equality of two {@link ListMultimap} instances depends on the ordering
+ * of the values for each key.
+ *
+ * <p>A non-empty {@link SetMultimap} cannot be equal to a non-empty
+ * {@link ListMultimap}, since their {@link #asMap} views contain unequal
+ * collections as values. However, any two empty multimaps are equal, because
+ * they both have empty {@link #asMap} views.
+ */
+ boolean equals(@Nullable Object obj);
+
+ /**
+ * Returns the hash code for this multimap.
+ *
+ * <p>The hash code of a multimap is defined as the hash code of the map view,
+ * as returned by {@link Multimap#asMap}.
+ */
+ int hashCode();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimaps.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimaps.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multimaps.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,1400 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+import org.richfaces.collections.base.Function;
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Supplier;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Map.Entry;
+
+/**
+ * Provides static methods acting on or generating a {@code Multimap}.
+ *
+ * @author Jared Levy
+ * @author Robert Konigsberg
+ * @author Mike Bostock
+ */
+public final class Multimaps {
+ private Multimaps() {}
+
+ /**
+ * Creates an empty {@code HashMultimap} instance.
+ *
+ * @return a newly-created, initially-empty {@code HashMultimap}
+ */
+ public static <K, V> HashMultimap<K, V> newHashMultimap() {
+ return new HashMultimap<K, V>();
+ }
+
+ /**
+ * Creates a {@code HashMultimap} instance initialized with all elements from
+ * the supplied {@code Multimap}. If the supplied multimap contains duplicate
+ * key-value pairs, those duplicate pairs will only be stored once in the new
+ * multimap.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap.
+ * @return a newly-created and initialized {@code HashMultimap}
+ */
+ public static <K, V> HashMultimap<K, V> newHashMultimap(
+ Multimap<? extends K, ? extends V> multimap) {
+ return new HashMultimap<K, V>(multimap);
+ }
+
+ /**
+ * Creates an empty {@code ArrayListMultimap} instance.
+ *
+ * @return a newly-created, initially-empty {@code ArrayListMultimap}
+ */
+ public static <K, V> ArrayListMultimap<K, V> newArrayListMultimap() {
+ return new ArrayListMultimap<K, V>();
+ }
+
+ /**
+ * Creates an {@code ArrayListMultimap} instance initialized with all elements
+ * from the supplied {@code Multimap}.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap.
+ * @return a newly-created and initialized {@code ArrayListMultimap}
+ */
+ public static <K, V> ArrayListMultimap<K, V> newArrayListMultimap(
+ Multimap<? extends K, ? extends V> multimap) {
+ return new ArrayListMultimap<K, V>(multimap);
+ }
+
+ /**
+ * Creates an empty {@code LinkedHashMultimap} instance.
+ *
+ * @return a newly-created, initially-empty {@code LinkedHashMultimap}
+ */
+ public static <K, V> LinkedHashMultimap<K, V> newLinkedHashMultimap() {
+ return new LinkedHashMultimap<K, V>();
+ }
+
+ /**
+ * Creates a {@code LinkedHashMultimap} instance initialized with all elements
+ * from the supplied {@code Multimap}. If the supplied multimap contains
+ * duplicate key-value pairs, those duplicate pairs will only be stored once
+ * in the new multimap. The new multimap has the same
+ * {@link Multimap#entries()} iteration order as the input multimap, except
+ * for excluding duplicate mappings.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap.
+ * @return a newly-created and initialized {@code LinkedHashMultimap}
+ */
+ public static <K, V> LinkedHashMultimap<K, V> newLinkedHashMultimap(
+ Multimap<? extends K, ? extends V> multimap) {
+ return new LinkedHashMultimap<K, V>(multimap);
+ }
+
+ /**
+ * Creates an empty {@code TreeMultimap} instance using the natural ordering
+ * of keys and values. If the supplied multimap contains duplicate key-value
+ * pairs, those duplicate pairs will only be stored once in the new multimap.
+ *
+ * @return a newly-created, initially-empty {@code TreeMultimap}
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <K extends Comparable, V extends Comparable>
+ TreeMultimap<K, V> newTreeMultimap() {
+ return new TreeMultimap<K, V>();
+ }
+
+ /**
+ * Constructs a {@code TreeMultimap} with the same mappings as the specified
+ * {@code Multimap}.
+ *
+ * <p>If the supplied multimap is an instance of {@code TreeMultimap}, the
+ * supplied multimap's comparators are copied to the new instance.
+ *
+ * <p>If the supplied multimap is not an instance of {@code TreeMultimap}, the
+ * new multimap is ordered using the natural ordering of the key and value
+ * classes. The key and value classes must satisfy the {@link Comparable}
+ * interface.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap.
+ * @return a newly-created and initialized {@code TreeMultimap}
+ */
+ public static <K, V> TreeMultimap<K, V> newTreeMultimap(
+ Multimap<? extends K, ? extends V> multimap) {
+ return new TreeMultimap<K, V>(multimap);
+ }
+
+ /**
+ * Creates an empty {@code TreeMultimap} instance using explicit comparators.
+ *
+ * @param keyComparator the comparator that determines the key ordering. If
+ * it's {@code null}, the natural ordering of the keys is used.
+ * @param valueComparator the comparator that determines the value ordering.
+ * If it's {@code null}, the natural ordering of the values is used.
+ * @return a newly-created, initially-empty {@code TreeMultimap}
+ */
+ public static <K, V> TreeMultimap<K, V> newTreeMultimap(
+ @Nullable Comparator<? super K> keyComparator,
+ @Nullable Comparator<? super V> valueComparator) {
+ return new TreeMultimap<K, V>(keyComparator, valueComparator);
+ }
+
+ /**
+ * Creates a {@code TreeMultimap} instance using explicit comparators,
+ * initialized with all elements from the supplied {@code Multimap}.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap.
+ * @return a newly-created and initialized {@code TreeMultimap}
+ */
+ public static <K, V> TreeMultimap<K, V> newTreeMultimap(
+ @Nullable Comparator<? super K> keyComparator,
+ @Nullable Comparator<? super V> valueComparator,
+ Multimap<? extends K, ? extends V> multimap) {
+ return new TreeMultimap<K, V>(keyComparator, valueComparator, multimap);
+ }
+
+ /**
+ * Creates a new {@code Multimap} that uses the provided map and factory. It
+ * can generate a multimap based on arbitrary {@link Map} and
+ * {@link Collection} classes.
+ *
+ * <p>The {@code factory}-generated and {@code map} classes determine the
+ * multimap iteration order. They also specify the behavior of the
+ * {@code equals}, {@code hashCode}, and {@code toString} methods for the
+ * multimap and its returned views. However, the multimaps's {@code get}
+ * method returns instances of a different class than {@code factory.get()}
+ * does.
+ *
+ * <p>The multimap is serializable if {@code map}, {@code factory}, the
+ * collections generated by {@code factory}, and the multimap contents are all
+ * serializable.
+ *
+ * <p>The multimap is not threadsafe when any concurrent operations update the
+ * multimap, even if {@code map} and the instances generated by
+ * {@code factory} are. Concurrent read operations will work correctly. To
+ * allow concurrent update operations, wrap the multimap with a call to
+ * {@link #synchronizedMultimap}.
+ *
+ * <p>Call this method only when the simpler methods
+ * {@link #newArrayListMultimap()}, {@link #newHashMultimap()},
+ * {@link #newLinkedHashMultimap()} and {@link #newTreeMultimap()} won't
+ * suffice.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ * @param factory supplier of new empty collections that will each hold all
+ * values for a given key
+ * @throws IllegalArgumentException if {@code map} is not empty
+ */
+ public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map,
+ final Supplier<? extends Collection<V>> factory) {
+ return new CustomMultimap<K, V>(map, factory);
+ }
+
+ private static class CustomMultimap<K, V> extends StandardMultimap<K, V> {
+ transient Supplier<? extends Collection<V>> factory;
+
+ CustomMultimap(Map<K, Collection<V>> map,
+ Supplier<? extends Collection<V>> factory) {
+ super(map);
+ this.factory = checkNotNull(factory);
+ }
+
+ @Override protected Collection<V> createCollection() {
+ return factory.get();
+ }
+
+ // can't use Serialization writeMultimap and populateMultimap methods since
+ // there's no way to generate the empty backing map.
+
+ /** @serialData the factory and the backing map */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(factory);
+ stream.writeObject(backingMap());
+ }
+
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ factory = (Supplier<? extends Collection<V>>) stream.readObject();
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ setMap(map);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a new {@code ListMultimap} that uses the provided map and factory.
+ * It can generate a multimap based on arbitrary {@link Map} and {@link List}
+ * classes.
+ *
+ * <p>The {@code factory}-generated and {@code map} classes determine the
+ * multimap iteration order. They also specify the behavior of the
+ * {@code equals}, {@code hashCode}, and {@code toString} methods for the
+ * multimap and its returned views. However, the multimaps's {@code get}
+ * method returns instances of a different class than {@code factory.get()}
+ * does.
+ *
+ * <p>The multimap is serializable if {@code map}, {@code factory}, the
+ * lists generated by {@code factory}, and the multimap contents are all
+ * serializable.
+ *
+ * <p>The multimap is not threadsafe when any concurrent operations update the
+ * multimap, even if {@code map} and the instances generated by
+ * {@code factory} are. Concurrent read operations will work correctly. To
+ * allow concurrent update operations, wrap the multimap with a call to
+ * {@link #synchronizedListMultimap}.
+ *
+ * <p>Call this method only when the simpler method {@link
+ * #newArrayListMultimap()} won't suffice.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ * @param factory supplier of new empty lists that will each hold all values
+ * for a given key
+ * @throws IllegalArgumentException if {@code map} is not empty
+ */
+ public static <K, V> ListMultimap<K, V> newListMultimap(
+ Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
+ return new CustomListMultimap<K, V>(map, factory);
+ }
+
+ private static class CustomListMultimap<K, V>
+ extends StandardListMultimap<K, V> {
+ transient Supplier<? extends List<V>> factory;
+
+ CustomListMultimap(Map<K, Collection<V>> map,
+ Supplier<? extends List<V>> factory) {
+ super(map);
+ this.factory = checkNotNull(factory);
+ }
+
+ @Override protected List<V> createCollection() {
+ return factory.get();
+ }
+
+ /** @serialData the factory and the backing map */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(factory);
+ stream.writeObject(backingMap());
+ }
+
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ factory = (Supplier<? extends List<V>>) stream.readObject();
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ setMap(map);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a new {@code SetMultimap} that uses the provided map and factory.
+ * It can generate a multimap based on arbitrary {@link Map} and {@link Set}
+ * classes.
+ *
+ * <p>The {@code factory}-generated and {@code map} classes determine the
+ * multimap iteration order. They also specify the behavior of the
+ * {@code equals}, {@code hashCode}, and {@code toString} methods for the
+ * multimap and its returned views. However, the multimaps's {@code get}
+ * method returns instances of a different class than {@code factory.get()}
+ * does.
+ *
+ * <p>The multimap is serializable if {@code map}, {@code factory}, the
+ * sets generated by {@code factory}, and the multimap contents are all
+ * serializable.
+ *
+ * <p>The multimap is not threadsafe when any concurrent operations update the
+ * multimap, even if {@code map} and the instances generated by
+ * {@code factory} are. Concurrent read operations will work correctly. To
+ * allow concurrent update operations, wrap the multimap with a call to
+ * {@link #synchronizedSetMultimap}.
+ *
+ * <p>Call this method only when the simpler methods
+ * {@link #newHashMultimap()}, {@link #newLinkedHashMultimap()}, and
+ * {@link #newTreeMultimap()} won't suffice.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ * @param factory supplier of new empty sets that will each hold all values
+ * for a given key
+ * @throws IllegalArgumentException if {@code map} is not empty
+ */
+ public static <K, V> SetMultimap<K, V> newSetMultimap(
+ Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
+ return new CustomSetMultimap<K, V>(map, factory);
+ }
+
+ private static class CustomSetMultimap<K, V>
+ extends StandardSetMultimap<K, V> {
+ transient Supplier<? extends Set<V>> factory;
+
+ CustomSetMultimap(Map<K, Collection<V>> map,
+ Supplier<? extends Set<V>> factory) {
+ super(map);
+ this.factory = checkNotNull(factory);
+ }
+
+ @Override protected Set<V> createCollection() {
+ return factory.get();
+ }
+
+ /** @serialData the factory and the backing map */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(factory);
+ stream.writeObject(backingMap());
+ }
+
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ factory = (Supplier<? extends Set<V>>) stream.readObject();
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ setMap(map);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a new {@code SortedSetMultimap} that uses the provided map and
+ * factory. It can generate a multimap based on arbitrary {@link Map} and
+ * {@link SortedSet} classes.
+ *
+ * <p>The {@code factory}-generated and {@code map} classes determine the
+ * multimap iteration order. They also specify the behavior of the
+ * {@code equals}, {@code hashCode}, and {@code toString} methods for the
+ * multimap and its returned views. However, the multimaps's {@code get}
+ * method returns instances of a different class than {@code factory.get()}
+ * does.
+ *
+ * <p>The multimap is serializable if {@code map}, {@code factory}, the
+ * sets generated by {@code factory}, and the multimap contents are all
+ * serializable.
+ *
+ * <p>The multimap is not threadsafe when any concurrent operations update the
+ * multimap, even if {@code map} and the instances generated by
+ * {@code factory} are. Concurrent read operations will work correctly. To
+ * allow concurrent update operations, wrap the multimap with a call to
+ * {@link #synchronizedSortedSetMultimap}.
+ *
+ * <p>Call this method only when the simpler method {@link #newTreeMultimap()}
+ * won't suffice.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ * @param factory supplier of new empty sorted sets that will each hold
+ * all values for a given key
+ * @throws IllegalArgumentException if {@code map} is not empty
+ */
+ public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
+ Map<K, Collection<V>> map,
+ final Supplier<? extends SortedSet<V>> factory) {
+ return new CustomSortedSetMultimap<K, V>(map, factory);
+ }
+
+ private static class CustomSortedSetMultimap<K, V>
+ extends StandardSortedSetMultimap<K, V> {
+ transient Supplier<? extends SortedSet<V>> factory;
+ transient Comparator<? super V> valueComparator;
+
+ CustomSortedSetMultimap(Map<K, Collection<V>> map,
+ Supplier<? extends SortedSet<V>> factory) {
+ super(map);
+ this.factory = checkNotNull(factory);
+ valueComparator = factory.get().comparator();
+ }
+
+ @Override protected SortedSet<V> createCollection() {
+ return factory.get();
+ }
+
+ /*@Override*/ public Comparator<? super V> valueComparator() {
+ return valueComparator;
+ }
+
+ /** @serialData the factory and the backing map */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(factory);
+ stream.writeObject(backingMap());
+ }
+
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
+ valueComparator = factory.get().comparator();
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ setMap(map);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a {@code HashMultimap} that's the inverse of the provided multimap.
+ * If the input multimap includes the mapping from a key to a value, the
+ * returned multimap contains a mapping from the value to the key.
+ *
+ * <p>If the input multimap has duplicate key-value mappings, the returned
+ * multimap includes the inverse mapping once.
+ *
+ * <p>The returned multimap is modifiable. Updating it will not affect the
+ * input multimap, and vice versa.
+ *
+ * @param multimap the multimap to invert
+ * @return the inverse of the input multimap
+ */
+ public static <K, V> HashMultimap<V, K> inverseHashMultimap(
+ Multimap<K, V> multimap) {
+ HashMultimap<V, K> inverse = new HashMultimap<V, K>();
+ addInverse(inverse, multimap);
+ return inverse;
+ }
+
+ /**
+ * Creates an {@code ArrayListMultimap} that's the inverse of the provided
+ * multimap. If the input multimap includes the mapping from a key to a value,
+ * the returned multimap contains a mapping from the value to the key.
+ *
+ * <p>The returned multimap is modifiable. Updating it will not affect the
+ * input multimap, and vice versa.
+ *
+ * @param multimap the multimap to invert
+ * @return the inverse of the input multimap
+ */
+ public static <K, V> ArrayListMultimap<V, K> inverseArrayListMultimap(
+ Multimap<K, V> multimap) {
+ ArrayListMultimap<V, K> inverse = new ArrayListMultimap<V, K>();
+ addInverse(inverse, multimap);
+ return inverse;
+ }
+
+ /**
+ * Creates a {@code TreeMultimap} that's the inverse of the provided multimap.
+ * If the input multimap includes the mapping from a key to a value, the
+ * returned multimap contains a mapping from the value to the key. The
+ * returned multimap follows the natural ordering of its keys and values.
+ *
+ * <p>If the input multimap has duplicate key-value mappings, the returned
+ * multimap includes the inverse mapping once.
+ *
+ * <p>The returned multimap is modifiable. Updating it will not affect the
+ * input map, and vice versa. The returned multimap orders the keys and values
+ * according to their natural ordering.
+ *
+ * @param multimap the multimap to invert
+ * @return the inverse of the input multimap
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <K extends Comparable, V extends Comparable> TreeMultimap<V, K>
+ inverseTreeMultimap(Multimap<K, V> multimap) {
+ TreeMultimap<V, K> inverse = new TreeMultimap<V, K>();
+ addInverse(inverse, multimap);
+ return inverse;
+ }
+
+ /** Inverts a multimap's entries and puts them in the inverse multimap. */
+ private static <K, V> void addInverse(Multimap<V, K> inverse,
+ Multimap<K, V> multimap) {
+ for (Map.Entry<K, V> entry : multimap.entries()) {
+ inverse.put(entry.getValue(), entry.getKey());
+ }
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) multimap backed by the specified
+ * multimap. In order to guarantee serial access, it is critical that
+ * <b>all</b> access to the backing multimap is accomplished through the
+ * returned multimap.
+ *
+ * <p>It is imperative that the user manually synchronize on the returned map
+ * when accessing any of its collection views:
+ *
+ * <pre> Multimap<K,V> m = Multimaps.synchronizedMultimap(
+ * new HashMultimap<K,V>());
+ * ...
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (m) { // Synchronizing on m, not s!
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that aren't
+ * synchronized.
+ *
+ * @param multimap the multimap to be wrapped in a synchronized view
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> Multimap<K, V> synchronizedMultimap(
+ Multimap<K, V> multimap) {
+ return Synchronized.multimap(multimap, null);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified multimap. Query operations on
+ * the returned multimap "read through" to the specified multimap, and
+ * attempts to modify the returned multimap, either directly or through the
+ * multimap's views, result in an {@code UnsupportedOperationException}.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are
+ * modifiable.
+ *
+ * @param delegate the multimap for which an unmodifiable view is to be
+ * returned
+ * @return an unmodifiable view of the specified multimap
+ */
+ public static <K, V> Multimap<K, V> unmodifiableMultimap(
+ Multimap<K, V> delegate) {
+ return new UnmodifiableMultimap<K, V>(delegate);
+ }
+
+ private static class UnmodifiableMultimap<K, V>
+ extends ForwardingMultimap<K, V> implements Serializable {
+ final Multimap<K, V> delegate;
+ transient volatile Collection<Entry<K, V>> entries;
+ transient volatile Multiset<K> keys;
+ transient volatile Set<K> keySet;
+ transient volatile Collection<V> values;
+ transient volatile Map<K, Collection<V>> map;
+
+ UnmodifiableMultimap(final Multimap<K, V> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override protected Multimap<K, V> delegate() {
+ return delegate;
+ }
+
+ @Override public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public Map<K, Collection<V>> asMap() {
+ if (map == null) {
+ final Map<K, Collection<V>> unmodifiableMap
+ = Collections.unmodifiableMap(delegate.asMap());
+ map = new ForwardingMap<K, Collection<V>>() {
+ @Override protected Map<K, Collection<V>> delegate() {
+ return unmodifiableMap;
+ }
+
+ Set<Entry<K, Collection<V>>> entrySet;
+
+ @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
+ Set<Entry<K, Collection<V>>> result = entrySet;
+ return (result == null)
+ ? entrySet
+ = unmodifiableAsMapEntries(unmodifiableMap.entrySet())
+ : result;
+ }
+
+ @Override public Collection<V> get(Object key) {
+ Collection<V> collection = unmodifiableMap.get(key);
+ return (collection == null)
+ ? null : unmodifiableValueCollection(collection);
+ }
+
+ Collection<Collection<V>> asMapValues;
+
+ @Override public Collection<Collection<V>> values() {
+ Collection<Collection<V>> result = asMapValues;
+ return (result == null)
+ ? asMapValues
+ = new UnmodifiableAsMapValues<V>(unmodifiableMap.values())
+ : result;
+ }
+
+ @Override public boolean containsValue(Object o) {
+ return values().contains(o);
+ }
+ };
+ }
+ return map;
+ }
+
+ @Override public Collection<Entry<K, V>> entries() {
+ if (entries == null) {
+ entries = unmodifiableEntries(delegate.entries());
+ }
+ return entries;
+ }
+
+ @Override public Collection<V> get(K key) {
+ return unmodifiableValueCollection(delegate.get(key));
+ }
+
+ @Override public Multiset<K> keys() {
+ if (keys == null) {
+ keys = Multisets.unmodifiableMultiset(delegate.keys());
+ }
+ return keys;
+ }
+
+ @Override public Set<K> keySet() {
+ if (keySet == null) {
+ keySet = Collections.unmodifiableSet(delegate.keySet());
+ }
+ return keySet;
+ }
+
+ @Override @SuppressWarnings("unused")
+ public boolean put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override @SuppressWarnings("unused")
+ public boolean putAll(K key,
+ @SuppressWarnings("hiding") Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override @SuppressWarnings("unused")
+ public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override @SuppressWarnings("unused")
+ public boolean remove(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override @SuppressWarnings("unused")
+ public Collection<V> removeAll(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override @SuppressWarnings("unused")
+ public Collection<V> replaceValues(K key,
+ @SuppressWarnings("hiding") Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public Collection<V> values() {
+ if (values == null) {
+ values = Collections.unmodifiableCollection(delegate.values());
+ }
+ return values;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private static class UnmodifiableAsMapValues<V>
+ extends ForwardingCollection<Collection<V>> {
+ final Collection<Collection<V>> delegate;
+ UnmodifiableAsMapValues(Collection<Collection<V>> delegate) {
+ this.delegate = Collections.unmodifiableCollection(delegate);
+ }
+ @Override protected Collection<Collection<V>> delegate() {
+ return delegate;
+ }
+ @Override public Iterator<Collection<V>> iterator() {
+ final Iterator<Collection<V>> iterator = delegate.iterator();
+ return new Iterator<Collection<V>>() {
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ public Collection<V> next() {
+ return unmodifiableValueCollection(iterator.next());
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+ @Override public boolean contains(Object o) {
+ return Iterators.contains(iterator(), o);
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+ }
+
+ private static class UnmodifiableListMultimap<K, V>
+ extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> {
+ UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
+ super(delegate);
+ }
+ @Override public ListMultimap<K, V> delegate() {
+ return (ListMultimap<K, V>) super.delegate();
+ }
+ @Override public List<V> get(K key) {
+ return Collections.unmodifiableList(delegate().get(key));
+ }
+ @Override public List<V> removeAll(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ @Override public List<V> replaceValues(
+ K key, @SuppressWarnings("hiding") Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private static class UnmodifiableSetMultimap<K, V>
+ extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> {
+ UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
+ super(delegate);
+ }
+ @Override public SetMultimap<K, V> delegate() {
+ return (SetMultimap<K, V>) super.delegate();
+ }
+ @Override public Set<V> get(K key) {
+ /*
+ * Note that this doesn't return a SortedSet when delegate is a
+ * SortedSetMultiset, unlike (SortedSet<V>) super.get().
+ */
+ return Collections.unmodifiableSet(delegate().get(key));
+ }
+ @Override public Set<Map.Entry<K, V>> entries() {
+ return Maps.unmodifiableEntrySet(delegate().entries());
+ }
+ @Override public Set<V> removeAll(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ @Override public Set<V> replaceValues(
+ K key, @SuppressWarnings("hiding") Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private static class UnmodifiableSortedSetMultimap<K, V>
+ extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> {
+ UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
+ super(delegate);
+ }
+ @Override public SortedSetMultimap<K, V> delegate() {
+ return (SortedSetMultimap<K, V>) super.delegate();
+ }
+ @Override public SortedSet<V> get(K key) {
+ return Collections.unmodifiableSortedSet(delegate().get(key));
+ }
+ @Override public SortedSet<V> removeAll(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ @Override public SortedSet<V> replaceValues(
+ K key, @SuppressWarnings("hiding") Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+ public Comparator<? super V> valueComparator() {
+ return delegate().valueComparator();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the
+ * specified multimap.
+ *
+ * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
+ *
+ * @param multimap the multimap to be wrapped
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(
+ SetMultimap<K, V> multimap) {
+ return Synchronized.setMultimap(multimap, null);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified {@code SetMultimap}. Query
+ * operations on the returned multimap "read through" to the specified
+ * multimap, and attempts to modify the returned multimap, either directly or
+ * through the multimap's views, result in an
+ * {@code UnsupportedOperationException}.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are
+ * modifiable.
+ *
+ * @param delegate the multimap for which an unmodifiable view is to be
+ * returned
+ * @return an unmodifiable view of the specified multimap
+ */
+ public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
+ SetMultimap<K, V> delegate) {
+ return new UnmodifiableSetMultimap<K, V>(delegate);
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by
+ * the specified multimap.
+ *
+ * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
+ *
+ * @param multimap the multimap to be wrapped
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> SortedSetMultimap<K, V>
+ synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) {
+ return Synchronized.sortedSetMultimap(multimap, null);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified {@code SortedSetMultimap}.
+ * Query operations on the returned multimap "read through" to the specified
+ * multimap, and attempts to modify the returned multimap, either directly or
+ * through the multimap's views, result in an
+ * {@code UnsupportedOperationException}.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are
+ * modifiable.
+ *
+ * @param delegate the multimap for which an unmodifiable view is to be
+ * returned
+ * @return an unmodifiable view of the specified multimap
+ */
+ public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
+ SortedSetMultimap<K, V> delegate) {
+ return new UnmodifiableSortedSetMultimap<K, V>(delegate);
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the
+ * specified multimap.
+ *
+ * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
+ *
+ * @param multimap the multimap to be wrapped
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> ListMultimap<K, V> synchronizedListMultimap(
+ ListMultimap<K, V> multimap) {
+ return Synchronized.listMultimap(multimap, null);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified {@code ListMultimap}. Query
+ * operations on the returned multimap "read through" to the specified
+ * multimap, and attempts to modify the returned multimap, either directly or
+ * through the multimap's views, result in an
+ * {@code UnsupportedOperationException}.
+ *
+ * <p>Note that the generated multimap's {@link Multimap#removeAll} and
+ * {@link Multimap#replaceValues} methods return collections that are
+ * modifiable.
+ *
+ * @param delegate the multimap for which an unmodifiable view is to be
+ * returned
+ * @return an unmodifiable view of the specified multimap
+ */
+ public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
+ ListMultimap<K, V> delegate) {
+ return new UnmodifiableListMultimap<K, V>(delegate);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified collection, preserving the
+ * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and
+ * {@code Collection}, in that order of preference.
+ *
+ * @param collection the collection for which to return an unmodifiable view
+ * @return an unmodifiable view of the collection
+ */
+ private static <V> Collection<V> unmodifiableValueCollection(
+ Collection<V> collection) {
+ if (collection instanceof SortedSet) {
+ return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
+ } else if (collection instanceof Set) {
+ return Collections.unmodifiableSet((Set<V>) collection);
+ } else if (collection instanceof List) {
+ return Collections.unmodifiableList((List<V>) collection);
+ }
+ return Collections.unmodifiableCollection(collection);
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified multimap {@code asMap} entry.
+ * The {@link Entry#setValue} operation throws an {@link
+ * UnsupportedOperationException}, and the collection returned by {@code
+ * getValue} is also an unmodifiable (type-preserving) view. This also has the
+ * side-effect of redefining equals to comply with the Map.Entry contract, and
+ * to avoid a possible nefarious implementation of equals.
+ *
+ * @param entry the entry for which to return an unmodifiable view
+ * @return an unmodifiable view of the entry
+ */
+ private static <K, V> Map.Entry<K, Collection<V>> unmodifiableAsMapEntry(
+ final Map.Entry<K, Collection<V>> entry) {
+ checkNotNull(entry);
+ return new AbstractMapEntry<K, Collection<V>>() {
+ @Override public K getKey() {
+ return entry.getKey();
+ }
+
+ @Override public Collection<V> getValue() {
+ return unmodifiableValueCollection(entry.getValue());
+ }
+ };
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified collection of entries. The
+ * {@link Entry#setValue} operation throws an {@link
+ * UnsupportedOperationException}. If the specified collection is a {@code
+ * Set}, the returned collection is also a {@code Set}.
+ *
+ * @param entries the entries for which to return an unmodifiable view
+ * @return an unmodifiable view of the entries
+ */
+ private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
+ Collection<Entry<K, V>> entries) {
+ if (entries instanceof Set) {
+ return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
+ }
+ return new Maps.UnmodifiableEntries<K, V>(
+ Collections.unmodifiableCollection(entries));
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified set of {@code asMap} entries.
+ * The {@link Entry#setValue} operation throws an {@link
+ * UnsupportedOperationException}, as do any operations that attempt to modify
+ * the returned collection.
+ *
+ * @param asMapEntries the {@code asMap} entries for which to return an
+ * unmodifiable view
+ * @return an unmodifiable view of the collection entries
+ */
+ private static <K, V> Set<Entry<K, Collection<V>>> unmodifiableAsMapEntries(
+ Set<Entry<K, Collection<V>>> asMapEntries) {
+ return new UnmodifiableAsMapEntries<K, V>(
+ Collections.unmodifiableSet(asMapEntries));
+ }
+
+ /** @see Multimaps#unmodifiableAsMapEntries */
+ static class UnmodifiableAsMapEntries<K, V>
+ extends ForwardingSet<Entry<K, Collection<V>>> {
+ private final Set<Entry<K, Collection<V>>> delegate;
+ UnmodifiableAsMapEntries(Set<Entry<K, Collection<V>>> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override protected Set<Entry<K, Collection<V>>> delegate() {
+ return delegate;
+ }
+
+ @Override public Iterator<Entry<K, Collection<V>>> iterator() {
+ final Iterator<Entry<K, Collection<V>>> iterator = delegate.iterator();
+ return new ForwardingIterator<Entry<K, Collection<V>>>() {
+ @Override protected Iterator<Entry<K, Collection<V>>> delegate() {
+ return iterator;
+ }
+ @Override public Entry<K, Collection<V>> next() {
+ return unmodifiableAsMapEntry(iterator.next());
+ }
+ };
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+
+ @Override public boolean contains(Object o) {
+ return Maps.containsEntryImpl(delegate(), o);
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+
+ @Override public boolean equals(Object o) {
+ return Sets.equalsImpl(this, o);
+ }
+ }
+
+ /**
+ * Returns a multimap view of the specified map. The multimap is backed by the
+ * map, so changes to the map are reflected in the multimap, and vice versa.
+ * If the map is modified while an iteration over one of the multimap's
+ * collection views is in progress (except through the iterator's own {@code
+ * remove} operation, or through the {@code setValue} operation on a map entry
+ * returned by the iterator), the results of the iteration are undefined.
+ *
+ * <p>The multimap supports mapping removal, which removes the corresponding
+ * mapping from the map. It does not support any operations which might add
+ * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}.
+ *
+ * <p>The returned multimap will be serializable if the specified map is
+ * serializable.
+ *
+ * @param map the backing map for the returned multimap view
+ */
+ public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
+ return new MapMultimap<K, V>(map);
+ }
+
+ /** @see Multimaps#forMap */
+ private static class MapMultimap<K, V>
+ implements SetMultimap<K, V>, Serializable {
+ final Map<K, V> map;
+ transient volatile Map<K, Collection<V>> asMap;
+
+ MapMultimap(Map<K, V> map) {
+ this.map = checkNotNull(map);
+ }
+
+ public int size() {
+ return map.size();
+ }
+
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ public boolean containsKey(Object key) {
+ return map.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return map.containsValue(value);
+ }
+
+ public boolean containsEntry(Object key, Object value) {
+ return map.entrySet().contains(Maps.immutableEntry(key, value));
+ }
+
+ public Set<V> get(final K key) {
+ return new AbstractSet<V>() {
+ @Override public Iterator<V> iterator() {
+ return new Iterator<V>() {
+ int i;
+
+ public boolean hasNext() {
+ return (i == 0) && map.containsKey(key);
+ }
+
+ public V next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ i++;
+ return map.get(key);
+ }
+
+ public void remove() {
+ checkState(i == 1);
+ i = -1;
+ map.remove(key);
+ }
+ };
+ }
+
+ @Override public int size() {
+ return map.containsKey(key) ? 1 : 0;
+ }
+ };
+ }
+
+ public boolean put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean putAll(K key, Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Set<V> replaceValues(K key, Iterable<? extends V> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean remove(Object key, Object value) {
+ return map.entrySet().remove(Maps.immutableEntry(key, value));
+ }
+
+ public Set<V> removeAll(Object key) {
+ Set<V> values = new HashSet<V>(2);
+ if (!map.containsKey(key)) {
+ return values;
+ }
+ values.add(map.remove(key));
+ return values;
+ }
+
+ public void clear() {
+ map.clear();
+ }
+
+ public Set<K> keySet() {
+ return map.keySet();
+ }
+
+ public Multiset<K> keys() {
+ return Multisets.forSet(map.keySet());
+ }
+
+ public Collection<V> values() {
+ return map.values();
+ }
+
+ public Set<Entry<K, V>> entries() {
+ return map.entrySet();
+ }
+
+ public Map<K, Collection<V>> asMap() {
+ if (asMap == null) {
+ asMap = new AsMap();
+ }
+ return asMap;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SetMultimap)) {
+ return false;
+ }
+ Multimap<?, ?> m = (Multimap<?, ?>) o;
+ if (map.size() != m.size()) {
+ return false;
+ }
+ for (Entry<K, V> e : map.entrySet()) {
+ if (!m.containsEntry(e.getKey(), e.getValue())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append('{');
+ for (Entry<K, V> e : map.entrySet()) {
+ builder.append(e.getKey()).append("=[")
+ .append(e.getValue()).append("], ");
+ }
+ if (builder.length() > 1) {
+ builder.setLength(builder.length() - 2); // delete last comma and space
+ }
+ builder.append('}');
+ return builder.toString();
+ }
+
+ /** @see MapMultimap#asMap */
+ class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
+ @Override public int size() {
+ return map.size();
+ }
+
+ @Override public Iterator<Entry<K, Collection<V>>> iterator() {
+ return new Iterator<Entry<K, Collection<V>>>() {
+ final Iterator<K> keys = map.keySet().iterator();
+
+ public boolean hasNext() {
+ return keys.hasNext();
+ }
+ public Entry<K, Collection<V>> next() {
+ final K key = keys.next();
+ return new AbstractMapEntry<K, Collection<V>>() {
+ @Override public K getKey() {
+ return key;
+ }
+ @Override public Collection<V> getValue() {
+ return get(key);
+ }
+ };
+ }
+ public void remove() {
+ keys.remove();
+ }
+ };
+ }
+
+ @Override public boolean contains(Object o) {
+ if (!(o instanceof Entry)) {
+ return false;
+ }
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ if (!(entry.getValue() instanceof Set)) {
+ return false;
+ }
+ Set<?> set = (Set<?>) entry.getValue();
+ return (set.size() == 1)
+ && containsEntry(entry.getKey(), set.iterator().next());
+ }
+
+ @Override public boolean remove(Object o) {
+ if (!(o instanceof Entry)) {
+ return false;
+ }
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ if (!(entry.getValue() instanceof Set)) {
+ return false;
+ }
+ Set<?> set = (Set<?>) entry.getValue();
+ return (set.size() == 1)
+ && map.entrySet().remove(
+ Maps.immutableEntry(entry.getKey(), set.iterator().next()));
+ }
+ }
+
+ /** @see MapMultimap#asMap */
+ class AsMap extends NpeThrowingAbstractMap<K, Collection<V>> {
+ @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
+ return new AsMapEntries();
+ }
+
+ // The following methods are included for performance.
+
+ @Override public boolean containsKey(Object key) {
+ return map.containsKey(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override public Collection<V> get(Object key) {
+ Collection<V> collection = MapMultimap.this.get((K) key);
+ return collection.isEmpty() ? null : collection;
+ }
+
+ @Override public Collection<V> remove(Object key) {
+ Collection<V> collection = removeAll(key);
+ return collection.isEmpty() ? null : collection;
+ }
+ }
+ private static final long serialVersionUID = 7845222491160860175L;
+ }
+
+ /**
+ * Creates an index {@code ListMultimap} that contains the results of applying
+ * a specified function to each item in an {@code Iterable} of values. Each
+ * value will be stored as a value in the resulting multimap, yielding a
+ * multimap with the same size as the input iterable. The key used to
+ * store that value in the multimap will be the result of calling the function
+ * on that value. The resulting multimap is created as an unmodifiable snapshot,
+ * it does <em>not</em> reflect subsequent changes on the input iterable.
+ *
+ * <p>For example,
+ *
+ * <pre class="code">
+ * List<String> badGuys =
+ * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
+ * Function<String, Integer> stringLengthFunction = ...;
+ * Multimap<Integer, String> index
+ * = Multimaps.index(badGuys, stringLengthFunction);
+ * System.out.println(index); </pre>
+ *
+ * prints
+ *
+ * <pre class="code">
+ * {4=[Inky], 5=[Pinky, Pinky, Clyde], 6=[Blinky]} </pre>
+ *
+ * @param values the values to use when constructing the {@code ListMultimap}
+ * @param keyFunction the function used to produce the key for each value
+ * @return {@code ListMultimap} mapping the result of evaluating the function
+ * {@code keyFunction} on each value in the input collection to that value
+ */
+ public static <K, V> ListMultimap<K, V> index(Iterable<? extends V> values,
+ Function<? super V, ? extends K> keyFunction) {
+ ArrayListMultimap<K, V> index = newArrayListMultimap();
+ index(values, keyFunction, index);
+ return unmodifiableListMultimap(index);
+ }
+
+ /**
+ * Indexes the specified values into a {@code Multimap} by applying a
+ * specified function to each item in an {@code Iterable} of values. Each
+ * value will be stored as a value in the specified multimap. The key used to
+ * store that value in the multimap will be the result of calling the function
+ * on that value. Depending on the multimap implementation, duplicate entries
+ * (equal keys and equal values) may be collapsed.
+ *
+ * <p>For example,
+ *
+ * <pre class="code">
+ * List<String> badGuys =
+ * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
+ * Function<String, Integer> stringLengthFunction = ...;
+ * Multimap<Integer, String> index = Multimaps.newHashMultimap();
+ * Multimaps.index(badGuys, stringLengthFunction, index);
+ * System.out.println(index); </pre>
+ *
+ * prints
+ *
+ * <pre class="code">
+ * {4=[Inky], 5=[Pinky, Clyde], 6=[Blinky]} </pre>
+ *
+ * The {@link HashMultimap} collapses the duplicate occurrence of
+ * {@code (5, "Pinky")}.
+ *
+ * @param values the values to add to the multimap
+ * @param keyFunction the function used to produce the key for each value
+ * @param multimap the multimap to store the key value pairs
+ */
+ public static <K, V> void index(Iterable<? extends V> values,
+ Function<? super V, ? extends K> keyFunction, Multimap<K, V> multimap) {
+ checkNotNull(keyFunction);
+ checkNotNull(multimap);
+ for (V value : values) {
+ K key = keyFunction.apply(value);
+ multimap.put(key, value);
+ }
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * A collection that supports order-independent equality, like {@link Set}, but
+ * may have duplicate elements. A multiset is also sometimes called a
+ * <i>bag</i>.
+ *
+ * <p>Elements of a multiset that are equal to one another (see "Note on
+ * element equivalence", below) are referred to as <i>occurrences</i> of the
+ * same single element. The total number of occurrences of an element in a
+ * multiset is called the <i>count</i> of that element (the terms "frequency"
+ * and "multiplicity" are equivalent, but not used in this API). Since the count
+ * of an element is represented as an {@code int}, a multiset may never contain
+ * more than {@link Integer#MAX_VALUE} occurrences of any one element.
+ *
+ * <p>{@code Multiset} refines the specifications of several methods from
+ * {@code Collection}. It also defines an additional query operation, {@link
+ * #count}, which returns the count of an element. There are five new
+ * bulk-modification operations, for example {@link #add(Object,int)}, to add or
+ * remove multiple occurrences of an element at once, or to set the count of an
+ * element to a specific value. These modification operations are optional, but
+ * implementations which support the standard collection operations {@link
+ * #add(Object)} or {@link #remove(Object)} are encouraged to implement the
+ * related methods as well. Finally, two collection views are provided: {@link
+ * #elementSet} contains the distinct elements of the multiset "with duplicates
+ * collapsed", and {@link #entrySet} is similar but contains {@link Entry
+ * Multiset.Entry} instances, each providing both a distinct element and the
+ * count of that element.
+ *
+ * <p>In addition to these required methods, implementations of {@code
+ * Multiset} are expected to provide two {@code static} creation methods:
+ * {@code newInstance()}, returning an empty multiset, and {@code
+ * newInstance(Iterable<? extends E>)}, returning a multiset containing the
+ * given initial elements. This is simply a refinement of {@code Collection}'s
+ * constructor recommendations, reflecting the new developments of Java 5.
+ *
+ * <p>As with other collection types, the modification operations are optional,
+ * and should throw {@link UnsupportedOperationException} when they are not
+ * implemented. Most implementations should support either all add operations
+ * or none of them, all removal operations or none of them, and if and only if
+ * all of these are supported, the {@code setCount} methods as well.
+ *
+ *
+ * <p>(TODO: after writing the below section, I became very unsure
+ * if we really want to bother taking such an approach. I could
+ * instead just go to TreeMultiset and remind callers of the
+ * danger of using a comparator inconsistent with equals().)
+ *
+ *
+ * <p><b>Note on element equivalence:</b> Like all collections, a {@code
+ * Multiset} implementation often needs to compare two instances to see whether
+ * they are "the same." {@code Multiset} does not specify which equivalence
+ * relation will be used for this purpose; it is left implementation-dependent.
+ * For example, given non-null instances, {@link HashMultiset} uses the typical
+ * choice of relation : <pre> {@code
+ *
+ * {(x, y) | x.hashCode() == y.hashCode() && x.equals(y)}}</pre>
+ *
+ * ... whereas {@link TreeMultiset} instead uses the slightly-less-common
+ * relation: <pre> {@code
+ *
+ * {(x, y) | comparator.compare(x, y) == 0}}</pre>
+ *
+ * ... and other implementations may use something else entirely. This approach
+ * may seem novel compared to existing collection specifications such as {@link
+ * Set}, however, it matches precisely the <i>de facto</i> specifications of
+ * these interfaces. That is, in practice, it is well-known that JDK
+ * implementation classes such as {@link TreeSet} and {@link IdentityHashMap}
+ * freely substitute their own equivalence relations however it suits them.
+ *
+ * @author Kevin Bourrillion
+ */
+public interface Multiset<E> extends Collection<E> {
+ // Query Operations
+
+ /**
+ * Returns the number of occurrences of an element in this multiset (the
+ * <i>count</i> of the element). Note that for an {@link Object#equals}-based
+ * multiset, this gives the same result as {@link Collections#frequency}
+ * (which would presumably perform more poorly).
+ *
+ * <p><b>Note:</b> the utility method {@link Iterables#frequency} generalizes
+ * this operation; it correctly delegates to this method when dealing with a
+ * multiset, but it can also accept any other iterable type.
+ *
+ * @param element the element to count occurrences of
+ * @return the number of occurrences of the element in this multiset; possibly
+ * zero but never negative
+ */
+ int count(@Nullable Object element); // TODO: possibly rename getCount
+
+ // Bulk Operations
+
+ /**
+ * Adds a number of occurrences of an element to this multiset. Note that if
+ * {@code occurrences == 1}, this method has the identical effect to {@link
+ * #add(Object)}. This method is functionally equivalent (except in the case
+ * of overflow) to the call {@code addAll(Collections.nCopies(element,
+ * occurrences))}, which would presumably perform much more poorly.
+ *
+ * @param element the element to add occurrences of; may be {@code null} only
+ * if explicitly allowed by the implementation
+ * @param occurrences the number of occurrences of this element to add. May
+ * be zero, in which case no change will be made.
+ * @return the previous count of this element before the operation; possibly
+ * zero - TODO: make this the actual behavior!
+ * @throws IllegalArgumentException if {@code occurrences} is negative, or if
+ * this operation would result in more than {@link Integer#MAX_VALUE}
+ * occurrences of the element
+ * @throws NullPointerException if {@code element} is null and this
+ * implementation does not permit null elements. Note that if {@code
+ * occurrences} is zero, the implementation may opt to return normally.
+ */
+ boolean /*int*/ add(E element, int occurrences);
+
+ /**
+ * Conditionally removes a number of occurrences of an element from this
+ * multiset, provided that at least this many occurrences are present. If the
+ * count of the element is less than {@code occurrences}, no change is made.
+ * Note that if
+ * {@code occurrences == 1}, this is functionally equivalent to the call
+ * {@code remove(element)}.
+ *
+ *
+ * @param element the element to conditionally remove occurrences of
+ * @param occurrences the number of occurrences of this element to remove. May
+ * be zero, in which case no change will be made.
+ * @return {@code true} if the condition for modification was met. Unless
+ * {@code occurrences} is zero, this implies that the multiset was indeed
+ * modified.
+ * @throws IllegalArgumentException if {@code occurrences} is negative
+ */
+ int /*boolean*/ remove(@Nullable Object element, int occurrences);
+
+ /**
+ * Removes <b>all</b> occurrences of the specified element from this multiset.
+ * This method complements {@link Multiset#remove(Object)}, which removes only
+ * one occurrence at a time.
+ *
+ * TODO: Nuke this. Use setCount(e, 0).
+ *
+ * @param element the element whose occurrences should all be removed
+ * @return the number of occurrences successfully removed, possibly zero
+ */
+ int removeAllOccurrences(@Nullable Object element);
+
+ /**
+ * Adds or removes the necessary occurrences of an element such that the
+ * element attains the desired count.
+ *
+ * @param element the element to add or remove occurrences of; may be null
+ * only if explicitly allowed by the implementation
+ * @param count the desired count of this element in this multiset
+ * @return the previous count of this element before the operation; possibly
+ * zero
+ * @throws IllegalArgumentException if {@code count} is negative
+ * @throws NullPointerException if {@code element} is null and this
+ * implementation does not permit null elements. Note that if {@code
+ * count} is zero, the implementor may optionally return zero instead.
+ */
+ // int setCount(E element, int count);
+
+ /**
+ * Conditionally sets the count of an element to a new value, as described in
+ * {@link #setCount(Object,int)}, provided that the element has the expected
+ * current count. If the current count is not {@code oldCount}, no change is
+ * made.
+ *
+ * @param element the element to conditionally set the count of; may be null
+ * only if explicitly allowed by the implementation
+ * @return {@code true} if the condition for modification was met. Unless
+ * {@code oldCount == newCount}, this implies that the multiset was
+ * indeed modified.
+ * @throws IllegalArgumentException if {@code oldCount} or {@code newCount} is
+ * negative
+ * @throws NullPointerException if {@code element} is null and the
+ * implementation does not permit null elements. Note that if {@code
+ * oldCount} and {@code newCount} are both zero, the implementor may
+ * optionally return {@code true} instead.
+ */
+ // boolean setCount(E element, int oldCount, int newCount);
+
+ // Views
+
+ /**
+ * Returns the set of distinct elements contained in this multiset. The
+ * element set is backed by the same data as the multiset, so any change to
+ * either is immediately reflected in the other. The order of the elements in
+ * the element set is unspecified.
+ *
+ * <p>If the element set supports any removal operations, these necessarily
+ * cause <b>all</b> occurrences of the removed element(s) to be removed from
+ * the multiset. Implementations are not expected to support the add
+ * operations, although this is possible.
+ *
+ * <p>A common use for the element set is to find the number of distinct
+ * elements in the multiset: {@code elementSet().size()}.
+ *
+ * @return a view of the set of distinct elements in this multiset
+ */
+ Set<E> elementSet();
+
+ /**
+ * Returns a view of the contents of this multiset, grouped into {@code
+ * Multiset.Entry} instances, each providing an element of the multiset and
+ * the count of that element. This set contains exactly one entry for each
+ * distinct element in the multiset (thus it always has the same size as the
+ * {@link #elementSet}). The order of the elements in the element set is
+ * unspecified.
+ *
+ * <p>The entry set is backed by the same data as the multiset, so any change
+ * to either is immediately reflected in the other. However, multiset changes
+ * may or may not be reflected in any {@code Entry} instances already
+ * retrieved from the entry set (this is implementation-dependent).
+ * Furthermore, implementations are not required to support modifications to
+ * the entry set at all, and the {@code Entry} instances themselves don't
+ * even have methods for modification. See the specific implementation class
+ * for more details on how its entry set handles modifications.
+ *
+ * @return a set of entries representing the data of this multiset
+ */
+ Set<Entry<E>> entrySet();
+
+ /**
+ * An unmodifiable element-count pair for a multiset. The {@link
+ * Multiset#entrySet} method returns a view of the multiset whose elements
+ * are of this class. A multiset implementation may return Entry instances
+ * that are either live "read-through" views to the Multiset, or immutable
+ * snapshots. Note that this type is unrelated to the similarly-named type
+ * {@code Map.Entry}.
+ */
+ interface Entry<E> {
+
+ /**
+ * Returns the multiset element corresponding to this entry. Multiple calls
+ * to this method always return the same instance.
+ *
+ * @return the element corresponding to this entry
+ */
+ E getElement();
+
+ /**
+ * Returns the count of the associated element in the underlying multiset.
+ * This count may either be an unchanging snapshot of the count at the time
+ * the entry was retrieved, or a live view of the current count of the
+ * element in the multiset, depending on the implementation. Note that in
+ * the former case, this method can never return zero, while in the latter,
+ * it will return zero if all occurrences of the element were since removed
+ * from the multiset.
+ *
+ * @return the count of the element; never negative
+ */
+ int getCount();
+
+ /**
+ * {@inheritDoc}
+ *
+ * TODO: check this wrt TreeMultiset
+ *
+ * <p>Returns {@code true} if the given object is also a multiset entry and
+ * the two entries represent the same element and count. More formally, two
+ * entries {@code a} and {@code b} are equal if:
+ *
+ * <pre> ((a.getElement() == null)
+ * ? (b.getElement() == null) : a.getElement().equals(b.getElement()))
+ * && (a.getCount() == b.getCount())</pre>
+ */
+ boolean equals(Object o);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The hash code of a multiset entry for element {@code element} and
+ * count {@code count} is defined as:
+ *
+ * <pre> (element == null ? 0 : element.hashCode()) ^ count</pre>
+ */
+ int hashCode();
+
+ /**
+ * Returns the canonical string representation of this entry, defined as
+ * follows. If the count for this entry is one, this is simply the string
+ * representation of the corresponding element. Otherwise, it is the string
+ * representation of the element, followed by the three characters {@code
+ * " x "} (space, letter x, space), followed by the count.
+ */
+ String toString();
+ }
+
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this multiset for equality. Returns
+ * {@code true} if the given object is also a multiset and contains equal
+ * elements with equal counts, regardless of order.
+ *
+ * TODO: caveats about equivalence-relation.
+ */
+ boolean equals(@Nullable Object object);
+
+ /**
+ * Returns the hash code for this multiset. This is defined as the sum of
+ *
+ * <pre> (element == null ? 0 : element.hashCode()) ^ count(element)</pre>
+ *
+ * over all distinct elements in the multiset. It follows that a multiset and
+ * its entry set always have the same hash code.
+ */
+ int hashCode();
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>It is recommended, though not mandatory, that this method return the
+ * result of invoking {@link #toString} on the {@link #entrySet}, yielding a
+ * result such as
+ * <pre>
+ * [a x 3, c, d x 2, b x 0, e]
+ * </pre>
+ */
+ String toString();
+
+ // Refined Collection Methods
+
+ /**
+ * Determines whether this multiset contains the specified element.
+ *
+ * <p>This method refines {@link Collection#contains} to further specify that
+ * it <b>may not</b> throw an exception in response to {@code element} being
+ * null or of the wrong type.
+ *
+ * @param element the element to check for
+ * @return {@code true} if this multiset contains at least one occurrence of
+ * this element
+ */
+ boolean contains(@Nullable Object element);
+
+ /**
+ * Returns {@code true} if this multiset contains at least one occurrence of
+ * each element in the specified collection.
+ *
+ * <p>This method refines {@link Collection#containsAll} to further specify
+ * that it <b>may not</b> throw an exception in response to any of {@code
+ * elements} being null or of the wrong type.
+ *
+ * <p><b>Note:</b> this method does not take into account the occurrence
+ * count of an element in the two collections; it may still return {@code
+ * true} even if {@code elements} contains several occurrences of an element
+ * and this multiset contains only one. This is no different than any other
+ * collection type like {@link List}, but it may be unexpected to the user of
+ * a multiset.
+ *
+ * @param elements the collection of elements to be checked for containment in
+ * this multiset
+ * @return {@code true} if this multiset contains at least one occurrence of
+ * each element contained in {@code elements}
+ * @throws NullPointerException if {@code elements} is null
+ */
+ boolean containsAll(Collection<?> elements);
+
+ /**
+ * Adds a single occurrence of the specified element to this multiset.
+ *
+ * <p>This method refines {@link Collection#add}, which only <i>ensures</i>
+ * the presence of the element, to further specify that a successful call must
+ * always increment the count of the element, and the overall size of the
+ * collection, by one.
+ *
+ * @param element the element to add one occurrence of; may be null only if
+ * explicitly allowed by the implementation
+ * @return {@code true} always, since this call is required to modify the
+ * multiset, unlike other {@link Collection} types
+ * @throws NullPointerException if {@code element} is null and this
+ * implementation does not permit null elements
+ * @throws IllegalArgumentException if {@link Integer#MAX_VALUE} occurrences
+ * of {@code element} are already contained in this multiset
+ */
+ boolean add(E element);
+
+ /**
+ * Removes a <i>single</i> occurrence of the specified element from this
+ * multiset, if present.
+ *
+ * <p>This method refines {@link Collection#remove} to further specify that it
+ * <b>may not</b> throw an exception in response to {@code element} being null
+ * or of the wrong type.
+ *
+ * @param element the element to remove one occurrence of
+ * @return {@code true} if an occurrence was found and removed
+ */
+ boolean remove(@Nullable Object element);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method refines {@link Collection#removeAll} to further specify that
+ * it <b>may not</b> throw an exception in response to any of {@code elements}
+ * being null or of the wrong type.
+ */
+ boolean removeAll(Collection<?> c);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This method refines {@link Collection#retainAll} to further specify that
+ * it <b>may not</b> throw an exception in response to any of {@code elements}
+ * being null or of the wrong type.
+ */
+ boolean retainAll(Collection<?> c);
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multisets.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multisets.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Multisets.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Provides static utility methods for creating and working with {@link
+ * Multiset} instances.
+ *
+ * @author Kevin Bourrillion
+ * @author Mike Bostock
+ */
+public final class Multisets {
+ private Multisets() {}
+
+ /**
+ * Creates an empty {@code HashMultiset} using the default initial capacity
+ * (16 distinct elements).
+ */
+ public static <E> HashMultiset<E> newHashMultiset() {
+ return new HashMultiset<E>();
+ }
+
+ /**
+ * Creates a {@code HashMultiset} containing the specified elements, using the
+ * default initial capacity (16 distinct elements).
+ *
+ * @param elements the elements that the multiset should contain
+ */
+ public static <E> HashMultiset<E> newHashMultiset(E... elements) {
+ HashMultiset<E> multiset = new HashMultiset<E>();
+ Collections.addAll(multiset, elements);
+ return multiset;
+ }
+
+ /**
+ * Creates a {@code HashMultiset} containing the specified elements.
+ *
+ * @param elements the elements that the multiset should contain
+ */
+ public static <E> HashMultiset<E> newHashMultiset(
+ Iterable<? extends E> elements) {
+ return HashMultiset.create(elements);
+ }
+
+ /**
+ * Creates an empty {@code TreeMultiset} instance.
+ *
+ * @return a newly-created, initially-empty TreeMultiset
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <E extends Comparable> TreeMultiset<E> newTreeMultiset() {
+ return new TreeMultiset<E>();
+ }
+
+ /**
+ * Creates an empty {@code TreeMultiset} instance, sorted according to the
+ * specified comparator.
+ *
+ * @return a newly-created, initially-empty TreeMultiset
+ */
+ public static <E> TreeMultiset<E> newTreeMultiset(Comparator<? super E> c) {
+ return new TreeMultiset<E>(c);
+ }
+
+ /** Creates an empty {@code EnumMultiset}. */
+ public static <E extends Enum<E>> EnumMultiset<E> newEnumMultiset(
+ Class<E> type) {
+ return new EnumMultiset<E>(type);
+ }
+
+ /**
+ * Creates an {@code EnumMultiset} containing the specified elements.
+ *
+ * @throws IllegalArgumentException if {@code elements} is empty
+ */
+ public static <E extends Enum<E>> EnumMultiset<E> newEnumMultiset(
+ Iterable<E> elements) {
+ return new EnumMultiset<E>(elements);
+ }
+
+ /**
+ * Creates an {@code EnumMultiset} containing the specified elements.
+ *
+ * @throws IllegalArgumentException if {@code elements} is empty
+ */
+ public static <E extends Enum<E>> EnumMultiset<E> newEnumMultiset(
+ E... elements) {
+ checkArgument(elements.length > 0,
+ "newEnumMultiset requires at least one element");
+ EnumMultiset<E> multiset = newEnumMultiset(elements[0].getDeclaringClass());
+ Collections.addAll(multiset, elements);
+ return multiset;
+ }
+
+ /**
+ * Returns an unmodifiable view of the specified multiset. Query operations on
+ * the returned multiset "read through" to the specified multiset, and
+ * attempts to modify the returned multiset result in an
+ * {@link UnsupportedOperationException}.
+ *
+ * @param multiset the multiset for which an unmodifiable view is to be
+ * generated
+ * @return an unmodifiable view of the multiset
+ */
+ public static <E> Multiset<E> unmodifiableMultiset(Multiset<E> multiset) {
+ return new UnmodifiableMultiset<E>(multiset);
+ }
+
+ private static class UnmodifiableMultiset<E> extends ForwardingMultiset<E>
+ implements Serializable {
+ final Multiset<E> delegate;
+ private UnmodifiableMultiset(Multiset<E> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override protected Multiset<E> delegate() {
+ return delegate;
+ }
+
+ transient Set<E> elementSet;
+
+ @Override public Set<E> elementSet() {
+ Set<E> es = elementSet;
+ return (es == null)
+ ? elementSet = Collections.unmodifiableSet(delegate.elementSet())
+ : es;
+ }
+
+ transient Set<Multiset.Entry<E>> entrySet;
+
+ @Override public Set<Multiset.Entry<E>> entrySet() {
+ Set<Multiset.Entry<E>> es = entrySet;
+ return (es == null)
+ ? entrySet = Collections.unmodifiableSet(delegate.entrySet())
+ : es;
+ }
+
+ @Override public Iterator<E> iterator() {
+ return Iterators.unmodifiableIterator(delegate.iterator());
+ }
+
+ @Override public boolean add(E element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean add(E element, int occurences) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean addAll(Collection<? extends E> elementsToAdd) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean remove(Object element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public int remove(Object element, int occurrences) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public int removeAllOccurrences(Object element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean removeAll(Collection<?> elementsToRemove) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean retainAll(Collection<?> elementsToRetain) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) multiset backed by the specified
+ * multiset. In order to guarantee serial access, <b>all</b> access to the
+ * backing multiset must go through the returned multiset.
+ *
+ * <p>It is imperative that the user manually synchronize on the returned
+ * multiset when iterating over any of its collection views:
+ *
+ * <pre> Multiset<E> m = Multisets.synchronizedMultiset(
+ * new HashMultiset<E>());
+ * ...
+ * Set<E> s = m.elementSet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (m) { // Synchronizing on m, not s!
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>For a greater degree of concurrency, you may use a {@link
+ * ConcurrentMultiset}.
+ *
+ * @param multiset the multiset to be wrapped
+ * @return a synchronized view of the specified multiset
+ */
+ public static <E> Multiset<E> synchronizedMultiset(Multiset<E> multiset) {
+ return Synchronized.multiset(multiset, null);
+ }
+
+ /**
+ * Returns an immutable multiset entry with the specified element and count.
+ *
+ * @param e the element to be associated with the returned entry
+ * @param n the count to be associated with the returned entry
+ * @throws IllegalArgumentException if {@code n} is negative
+ */
+ public static <E> Multiset.Entry<E> immutableEntry(final E e, final int n) {
+ checkArgument(n >= 0);
+ return new AbstractMultisetEntry<E>() {
+ public E getElement() {
+ return e;
+ }
+ public int getCount() {
+ return n;
+ }
+ };
+ }
+
+ /**
+ * Returns a multiset view of the specified set. The multiset is backed by the
+ * set, so changes to the set are reflected in the multiset, and vice versa.
+ * If the set is modified while an iteration over the multiset is in progress
+ * (except through the iterator's own {@code remove} operation) the results of
+ * the iteration are undefined.
+ *
+ * <p>The multiset supports element removal, which removes the corresponding
+ * element from the set. It does not support the {@code add} or {@code addAll}
+ * operations.
+ *
+ * <p>The returned multiset will be serializable if the specified set is
+ * serializable. The multiset is threadsafe if the set is threadsafe.
+ *
+ * @param set the backing set for the returned multiset view
+ */
+ public static <E> Multiset<E> forSet(Set<E> set) {
+ return new SetMultiset<E>(set);
+ }
+
+ /** @see Multisets#forSet */
+ private static class SetMultiset<E> extends ForwardingCollection<E>
+ implements Multiset<E>, Serializable {
+ final Set<E> delegate;
+
+ SetMultiset(Set<E> set) {
+ delegate = checkNotNull(set);
+ }
+
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+
+ public int count(Object element) {
+ return delegate.contains(element) ? 1 : 0;
+ }
+
+ public boolean add(E element, int occurrences) {
+ throw new UnsupportedOperationException();
+ }
+
+ public int remove(Object element, int occurrences) {
+ if (occurrences == 0) {
+ return 0;
+ }
+ checkArgument(occurrences > 0);
+ return removeAllOccurrences(element);
+ }
+
+ public int removeAllOccurrences(Object element) {
+ return delegate.remove(element) ? 1 : 0;
+ }
+
+ transient Set<E> elementSet;
+
+ public Set<E> elementSet() {
+ Set<E> es = elementSet;
+ return (es == null) ? elementSet = new ElementSet() : es;
+ }
+
+ transient Set<Entry<E>> entrySet;
+
+ public Set<Entry<E>> entrySet() {
+ Set<Entry<E>> es = entrySet;
+ return (es == null) ? entrySet = new EntrySet() : es;
+ }
+
+ @Override public boolean add(E o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean addAll(Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Multiset)) {
+ return false;
+ }
+ Multiset<?> m = (Multiset<?>) o;
+ return size() == m.size() && delegate.equals(m.elementSet());
+ }
+
+ @Override public int hashCode() {
+ int sum = 0;
+ for (E e : this) {
+ sum += ((e == null) ? 0 : e.hashCode()) ^ 1;
+ }
+ return sum;
+ }
+
+ /** @see SetMultiset#elementSet */
+ class ElementSet extends ForwardingSet<E> {
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+
+ @Override public boolean add(E o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean addAll(Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /** @see SetMultiset#entrySet */
+ class EntrySet extends AbstractSet<Entry<E>> {
+ @Override public int size() {
+ return delegate.size();
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+ @Override public Iterator<Entry<E>> iterator() {
+ return new Iterator<Entry<E>>() {
+ final Iterator<E> elements = delegate.iterator();
+
+ public boolean hasNext() {
+ return elements.hasNext();
+ }
+ public Entry<E> next() {
+ return immutableEntry(elements.next(), 1);
+ }
+ public void remove() {
+ elements.remove();
+ }
+ };
+ }
+ // TODO: faster contains, remove
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns the expected number of distinct elements given the specified
+ * elements. The number of distinct elements is only computed if {@code
+ * elements} is an instance of {@code Multiset}; otherwise the default value
+ * of 11 is returned.
+ */
+ static int inferDistinctElements(Iterable<?> elements) {
+ if (elements instanceof Multiset) {
+ return ((Multiset<?>) elements).elementSet().size();
+ }
+ return 11; // initial capacity will be rounded up to 16
+ }
+
+ /**
+ * Returns a comparator that orders elements according to their increasing
+ * frequency in a multiset. For example, suppose {@code m} is a non-empty
+ * multiset of strings. Then:
+ *
+ * <pre> Collections.max(m.elementSet(), frequencyOrder(m));</pre>
+ *
+ * returns a string that occurs most frequently in {@code m}.
+ * (Warning: in this example, {@code Collections.max} throws
+ * {@code NoSuchElementException} when {@code m} is empty.)
+ *
+ * <p>The returned {@link Ordering} is a view into the backing multiset, so
+ * the ordering's behavior will change if the backing multiset changes. This
+ * can be dangerous; for example, if the ordering is used by a {@code TreeSet}
+ * and the backing multiset changes, the behavior of the {@code TreeSet}
+ * becomes undefined. Use a copy of the multiset to isolate against such
+ * changes when necessary.
+ *
+ * @param multiset the multiset specifying the frequencies of the objects to
+ * compare
+ */
+ public static <T> Ordering<T> frequencyOrder(Multiset<?> multiset) {
+ return new FrequencyOrder<T>(multiset);
+ }
+
+ /** @see Multisets#frequencyOrder(Multiset) */
+ private static class FrequencyOrder<T> extends Ordering<T> {
+ final Multiset<?> multiset;
+
+ FrequencyOrder(Multiset<?> multiset) {
+ this.multiset = checkNotNull(multiset);
+ }
+
+ public int compare(T left, T right) {
+ int leftCount = multiset.count(left);
+ int rightCount = multiset.count(right);
+ return Comparators.compare(leftCount, rightCount);
+ }
+
+ @Override public boolean equals(Object object) {
+ if (object instanceof FrequencyOrder) {
+ FrequencyOrder<?> that = (FrequencyOrder<?>) object;
+ return (this.multiset).equals(that.multiset);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return multiset.hashCode();
+ }
+
+ @Override public String toString() {
+ return "FrequencyOrder " + multiset;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/NpeThrowingAbstractMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/NpeThrowingAbstractMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/NpeThrowingAbstractMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * {@code AbstractMap} extension whose views have {@code removeAll} and
+ * {@code retainAll} methods that always throw an exception when given a null
+ * collection. It provides a workaround for <a
+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4802647">Sun bug
+ * 4802647</a>.
+ *
+ * @author Jared Levy
+ */
+abstract class NpeThrowingAbstractMap<K, V> extends AbstractMap<K, V> {
+
+ /**
+ * Supplies an entry set, a wrapped version of which is returned by
+ * {@code entrySet()}. That way, {@link #entrySet} retrieves an entry set
+ * whose {@link Set#retainAll} method always throws an exception.
+ *
+ * <p>This method is invoked at most once on a given map, at the time when
+ * {@code entrySet()} is first called.
+ */
+ protected abstract Set<Map.Entry<K, V>> createEntrySet();
+
+ private transient Set<Map.Entry<K, V>> entrySet;
+
+ @Override public synchronized Set<Map.Entry<K, V>> entrySet() {
+ if (entrySet == null) {
+ final Set<Map.Entry<K, V>> delegate = createEntrySet();
+ entrySet = new ForwardingSet<Map.Entry<K, V>>() {
+ @Override protected Set<Map.Entry<K, V>> delegate() {
+ return delegate;
+ }
+ };
+ }
+ return entrySet;
+ }
+
+ private transient Set<K> keySet;
+
+ @Override public synchronized Set<K> keySet() {
+ if (keySet == null) {
+ final Set<K> delegate = super.keySet();
+ keySet = new ForwardingSet<K>() {
+ @Override protected Set<K> delegate() {
+ return delegate;
+ }
+ };
+ }
+ return keySet;
+ }
+
+ private transient Collection<V> values;
+
+ @Override public synchronized Collection<V> values() {
+ if (values == null) {
+ final Collection<V> delegate = super.values();
+ values = new ForwardingCollection<V>() {
+ @Override protected Collection<V> delegate() {
+ return delegate;
+ }
+ };
+ }
+ return values;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ObjectArrays.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ObjectArrays.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ObjectArrays.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Static utility methods pertaining to object arrays.
+ *
+ * @author Kevin Bourrillion
+ */
+public final class ObjectArrays {
+ private ObjectArrays() {}
+
+ /** An empty object array. */
+ public static final Object[] EMPTY_ARRAY = new Object[0];
+
+ /**
+ * Returns a new array of the given length with the specified component type.
+ *
+ * @param type the component type
+ * @param length the length of the new array
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] newArray(Class<T> type, int length) {
+ return (T[]) Array.newInstance(type, length);
+ }
+
+ /**
+ * Returns a new array of the given length with the same type as a reference
+ * array.
+ *
+ * @param reference any array of the desired type
+ * @param length the length of the new array
+ */
+ public static <T> T[] newArray(T[] reference, int length) {
+ Class<?> type = reference.getClass().getComponentType();
+
+ // the cast is safe because result.getClass() == reference.getClass()
+ @SuppressWarnings("unchecked")
+ T[] result = (T[]) Array.newInstance(type, length);
+ return result;
+ }
+
+ /**
+ * Returns an empty array with the same component type as the specified array.
+ *
+ * @param array the array from which to infer the component type
+ */
+ public static <T> T[] emptyArray(T[] array) {
+ return (array.length == 0) ? array : newArray(array, 0);
+ }
+
+ /**
+ * Returns a new array that contains the concatenated contents of two arrays.
+ *
+ * @param first the first array of elements to concatenate
+ * @param second the second array of elements to concatenate
+ * @param type the component type of the returned array
+ */
+ public static <T> T[] concat(T[] first, T[] second, Class<T> type) {
+ T[] result = newArray(type, first.length + second.length);
+ System.arraycopy(first, 0, result, 0, first.length);
+ System.arraycopy(second, 0, result, first.length, second.length);
+ return result;
+ }
+
+ /**
+ * Returns an array containing all of the elements in the specified
+ * collection; the runtime type of the returned array is that of the specified
+ * array. If the collection fits in the specified array, it is returned
+ * therein. Otherwise, a new array is allocated with the runtime type of the
+ * specified array and the size of the specified collection.
+ *
+ * <p>If the collection fits in the specified array with room to spare (i.e.,
+ * the array has more elements than the collection), the element in the array
+ * immediately following the end of the collection is set to null. This is
+ * useful in determining the length of the collection <i>only</i> if the
+ * caller knows that the collection does not contain any null elements.
+ *
+ * <p>This method returns the elements in the order they are returned by the
+ * collection's iterator.
+ *
+ * <p>TODO: Support concurrent collections whose size can change while the
+ * method is running.
+ *
+ * @param c the collection for which to return an array of elements
+ * @param array the array in which to place the collection elements
+ * @throws ArrayStoreException if the runtime type of the specified array is
+ * not a supertype of the runtime type of every element in the specified
+ * collection
+ */
+ static <T> T[] toArrayImpl(Collection<?> c, T[] array) {
+ int size = c.size();
+ if (array.length < size) {
+ array = newArray(array, size);
+ }
+ fillArray(c, array);
+ if (array.length > size) {
+ array[size] = null;
+ }
+ return array;
+ }
+
+ /**
+ * Returns an array containing all of the elements in the specified
+ * collection. This method returns the elements in the order they are returned
+ * by the collection's iterator. The returned array is "safe" in that no
+ * references to it are maintained by the collection. The caller is thus free
+ * to modify the returned array.
+ *
+ * <p>This method assumes that the collection size doesn't change while the
+ * method is running.
+ *
+ * <p>TODO: Support concurrent collections whose size can change while the
+ * method is running.
+ *
+ * @param c the collection for which to return an array of elements
+ */
+ static Object[] toArrayImpl(Collection<?> c) {
+ return fillArray(c, new Object[c.size()]);
+ }
+
+ private static Object[] fillArray(Iterable<?> elements, Object[] array) {
+ int i = 0;
+ for (Object element : elements) {
+ array[i++] = element;
+ }
+ return array;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Ordering.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Ordering.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Ordering.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A base class for {@link Serializable} {@link Comparator comparators} that
+ * provides convenience methods for common uses.
+ *
+ * @author Jesse Wilson
+ */
+public abstract class Ordering<T> implements Comparator<T>, Serializable {
+
+ /**
+ * Returns an ordering that uses the natural order of the values. The ordering
+ * throws a {@link NullPointerException} when passed a null parameter.
+ *
+ * <p>The type specification is {@code <T extends Comparable>}, instead of
+ * the more specific {@code <T extends Comparable<? super T>>}, to support
+ * classes defined without generics.
+ */
+ @SuppressWarnings("unchecked") // see explanation in method Javadoc
+ public static <T extends Comparable> Ordering<T> natural() {
+ return Comparators.naturalOrder();
+ }
+
+ /**
+ * Returns an ordering for {@code comparator}.
+ *
+ * @param comparator the comparator that defines the order
+ */
+ public static <T> Ordering<T> forComparator(final Comparator<T> comparator) {
+ return new ComparatorOrdering<T>(comparator);
+ }
+
+ private static final class ComparatorOrdering<T> extends Ordering<T> {
+ private final Comparator<T> comparator;
+
+ private ComparatorOrdering(Comparator<T> comparator) {
+ this.comparator = checkNotNull(comparator);
+ }
+
+ public int compare(T a, T b) {
+ return comparator.compare(a, b);
+ }
+
+ @Override public boolean equals(Object other) {
+ return other instanceof ComparatorOrdering
+ && comparator.equals(((ComparatorOrdering<?>) other).comparator);
+ }
+
+ @Override public int hashCode() {
+ return comparator.hashCode();
+ }
+
+ @Override public String toString() {
+ return comparator.toString();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns the ordering that is the {@link
+ * Collections#reverseOrder(Comparator) reverse} of this ordering.
+ */
+ public Ordering<T> reverseOrder() {
+ return new ReverseOrdering<T>(this);
+ }
+
+ /**
+ * A reverse view of another ordering. Prefer this over {@link
+ * Collections#reverseOrder(Comparator)}, which does not implement
+ * {@code equals()} or {@code hashCode()}.
+ */
+ private static class ReverseOrdering<T> extends Ordering<T> {
+ final Ordering<T> forwardOrder;
+ public ReverseOrdering(Ordering<T> forwardOrder) {
+ this.forwardOrder = checkNotNull(forwardOrder);
+ }
+
+ @Override public Ordering<T> reverseOrder() {
+ return forwardOrder;
+ }
+
+ public int compare(T a, T b) {
+ return forwardOrder.compare(b, a);
+ }
+
+ @Override public int hashCode() {
+ return -forwardOrder.hashCode();
+ }
+
+ @Override public boolean equals(Object other) {
+ return other instanceof ReverseOrdering
+ && forwardOrder.equals(((ReverseOrdering<?>) other).forwardOrder);
+ }
+
+ @Override public String toString() {
+ return "reverseOrder(" + forwardOrder + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * {@link Collections#binarySearch(List, Object, Comparator) Searches}
+ * {@code sortedList} for {@code key} using the binary search algorithm. The
+ * list must be sorted using this ordering.
+ *
+ * @param sortedList the list to be searched
+ * @param key the key to be searched for
+ */
+ public int binarySearch(List<? extends T> sortedList, T key) {
+ return Collections.binarySearch(sortedList, key, this);
+ }
+
+ /**
+ * {@link Collections#sort(List, Comparator) Sorts} {@code list} according
+ * to this ordering.
+ *
+ * @param list the list to be sorted
+ */
+ public void sort(List<? extends T> list) {
+ Collections.sort(list, this);
+ }
+
+ /**
+ * Returns a copy of the given iterable sorted by this ordering. The input is
+ * not modified. The returned list is modifiable, serializable, and has random
+ * access.
+ *
+ * <p>Unlike {@link Sets#newTreeSet(Comparator, Iterable)}, this method does
+ * not collapse elements that compare as zero, and the resulting collection
+ * does not maintain its own sort order.
+ *
+ * @param iterable the elements to be copied and sorted
+ * @return a new list containing the given elements in sorted order
+ */
+ public <E extends T> List<E> sortedCopy(Iterable<E> iterable) {
+ List<E> list = Lists.newArrayList(iterable);
+ sort(list);
+ return list;
+ }
+
+ /**
+ * Returns the largest of the specified values according to this ordering. If
+ * there are multiple largest values, the first of those is returned.
+ *
+ * @param iterable the iterable whose maximum element is to be determined
+ * @throws java.util.NoSuchElementException if {@code iterable} is empty
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E max(Iterable<E> iterable) {
+ Iterator<E> iterator = iterable.iterator();
+
+ // let this throw NoSuchElementException as necessary
+ E maxSoFar = iterator.next();
+
+ while (iterator.hasNext()) {
+ maxSoFar = max(maxSoFar, iterator.next());
+ }
+
+ return maxSoFar;
+ }
+
+ /**
+ * Returns the largest of the specified values according to this ordering. If
+ * there are multiple largest values, the first of those is returned.
+ *
+ * @param a value to compare, returned if greater than or equal to the rest.
+ * @param b value to compare
+ * @param c value to compare
+ * @param rest values to compare
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E max(E a, E b, E c, E... rest) {
+ E maxSoFar = max(max(a, b), c);
+
+ for (E r : rest) {
+ maxSoFar = max(maxSoFar, r);
+ }
+
+ return maxSoFar;
+ }
+
+ /**
+ * Returns the larger of the two values according to this ordering. If the
+ * values compare as 0, the first is returned.
+ *
+ * @param a value to compare, returned if greater than or equal to b.
+ * @param b value to compare.
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E max(E a, E b) {
+ return compare(a, b) >= 0 ? a : b;
+ }
+
+ /**
+ * Returns the smallest of the specified values according to this ordering. If
+ * there are multiple smallest values, the first of those is returned.
+ *
+ * @param iterable the iterable whose minimum element is to be determined
+ * @throws java.util.NoSuchElementException if {@code iterable} is empty
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E min(Iterable<E> iterable) {
+ Iterator<E> iterator = iterable.iterator();
+
+ // let this throw NoSuchElementException as necessary
+ E minSoFar = iterator.next();
+
+ while (iterator.hasNext()) {
+ minSoFar = min(minSoFar, iterator.next());
+ }
+
+ return minSoFar;
+ }
+
+ /**
+ * Returns the smallest of the specified values according to this ordering. If
+ * there are multiple smallest values, the first of those is returned.
+ *
+ * @param a value to compare, returned if less than or equal to the rest.
+ * @param b value to compare
+ * @param c value to compare
+ * @param rest values to compare
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E min(E a, E b, E c, E... rest) {
+ E minSoFar = min(min(a, b), c);
+
+ for (E r : rest) {
+ minSoFar = min(minSoFar, r);
+ }
+
+ return minSoFar;
+ }
+
+ /**
+ * Returns the smaller of the two values according to this ordering. If the
+ * values compare as 0, the first is returned.
+ *
+ * @param a value to compare, returned if less than or equal to b.
+ * @param b value to compare.
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E min(E a, E b) {
+ return compare(a, b) <= 0 ? a : b;
+ }
+
+ /**
+ * Returns an ordering that treats {@code null} as less than all other values
+ * and uses this ordering to compare non-null values.
+ */
+ public Ordering<T> nullsFirst() {
+ // TODO: Rename Comparators.nullLeastOrder to nullsFirst.
+ return Comparators.nullLeastOrder(this);
+ }
+
+ /**
+ * Returns an ordering that treats {@code null} as greater than all other
+ * values and uses this ordering to compare non-null values.
+ */
+ public Ordering<T> nullsLast() {
+ // TODO: Rename Comparators.nullGreatestOrder to nullsLast.
+ return Comparators.nullGreatestOrder(this);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PeekingIterator.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PeekingIterator.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PeekingIterator.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Iterator;
+
+/**
+ * An iterator that supports a one-element lookahead while iterating.
+ *
+ * @author Mick Killianey
+ */
+public interface PeekingIterator<E> extends Iterator<E> {
+
+ /**
+ * Returns the next element in the iteration without advancing the iteration.
+ *
+ * <p>If possible, calls to {@code peek()} should not affect the iteration.
+ * As is the case with most Iterators, modifications to the underlying
+ * iteration may have unanticipated results.
+ *
+ * <p>If there are no remaining elements in the iteration, {@code peek()}
+ * will throw a {@code NoSuchElementException}. (A {@code null} return value
+ * does <em>not</em> indicate that this iterator has reached the end of its
+ * iteration.)
+ *
+ * <p><b>Usage note</b>: Implementations may, but are not required to,
+ * support {@code remove()} following a call to {@code peek()}.
+ *
+ * @throws java.util.NoSuchElementException if the iteration has
+ * no more elements.
+ */
+ E peek();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PrimitiveArrays.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PrimitiveArrays.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/PrimitiveArrays.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+
+/**
+ * Static utility methods pertaining to arrays of Java primitives.
+ *
+ * @author DJ Lee
+ * @author Michael Parker
+ * @author Jared Levy
+ */
+public final class PrimitiveArrays {
+ private PrimitiveArrays() {}
+
+ /*
+ * In the following *Array classes, the overrides of contains(), indexOf(),
+ * lastIndexOf(), equals(), hashCode(), and toString() are for performance
+ * reasons only. The list generated by subList(), which doesn't have those
+ * overrides, works correctly.
+ *
+ * TODO: Have subList return a class that overrides those methods.
+ */
+
+ private abstract static class PrimitiveArray<E> extends AbstractList<E>
+ implements RandomAccess, Serializable {
+ @Override public boolean contains(Object o) {
+ return (o != null) && super.contains(o);
+ }
+
+ @Override public int indexOf(Object o) {
+ return (o == null) ? -1 : super.indexOf(o);
+ }
+
+ @Override public int lastIndexOf(Object o) {
+ return (o == null) ? -1 : super.lastIndexOf(o);
+ }
+ }
+
+ // TODO: Enhance the to*Array methods to support concurrent collections whose
+ // size changes while the method is running.
+
+ /**
+ * Converts a collection of {@code Short} instances into a new array of
+ * primitive shorts.
+ *
+ * @param collection a collection of {@code Short} objects
+ * @return an array containing the same shorts as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static short[] toShortArray(Collection<Short> collection) {
+ int counter = 0;
+ short[] array = new short[collection.size()];
+ for (Short x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Short> asList(short[] backingArray) {
+ return new ShortArray(backingArray);
+ }
+
+ private static class ShortArray extends PrimitiveArray<Short> {
+ final short[] array;
+
+ ShortArray(short[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Short get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Short set(int index, Short element) {
+ Short oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof ShortArray) {
+ ShortArray otherShortArray = (ShortArray) o;
+ return Arrays.equals(array, otherShortArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Integer} instances into a new array of
+ * primitive ints.
+ *
+ * @param collection a collection of {@code Integer} objects
+ * @return an array containing the same ints as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static int[] toIntArray(Collection<Integer> collection) {
+ int counter = 0;
+ int[] array = new int[collection.size()];
+ for (Integer x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Integer> asList(int[] backingArray) {
+ return new IntegerArray(backingArray);
+ }
+
+ private static class IntegerArray extends PrimitiveArray<Integer> {
+ final int[] array;
+
+ IntegerArray(int[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Integer get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Integer set(int index, Integer element) {
+ Integer oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof IntegerArray) {
+ IntegerArray otherIntArray = (IntegerArray) o;
+ return Arrays.equals(array, otherIntArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Double} instances into a new array of
+ * primitive doubles.
+ *
+ * @param collection a collection of {@code Double} objects
+ * @return an array containing the same doubles as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static double[] toDoubleArray(Collection<Double> collection) {
+ int counter = 0;
+ double[] array = new double[collection.size()];
+ for (Double x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Double> asList(double[] backingArray) {
+ return new DoubleArray(backingArray);
+ }
+
+ private static class DoubleArray extends PrimitiveArray<Double> {
+ final double[] array;
+
+ DoubleArray(double[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Double get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Double set(int index, Double element) {
+ Double oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof DoubleArray) {
+ DoubleArray otherDoubleArray = (DoubleArray) o;
+ return Arrays.equals(array, otherDoubleArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Float} instances into a new array of
+ * primitive floats.
+ *
+ * @param collection a collection of {@code float} objects
+ * @return an array containing the same floats as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static float[] toFloatArray(Collection<Float> collection) {
+ int counter = 0;
+ float[] array = new float[collection.size()];
+ for (Float x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Float> asList(float[] backingArray) {
+ return new FloatArray(backingArray);
+ }
+
+ private static class FloatArray extends PrimitiveArray<Float> {
+ final float[] array;
+
+ FloatArray(float[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Float get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Float set(int index, Float element) {
+ Float oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof FloatArray) {
+ FloatArray otherFloatArray = (FloatArray) o;
+ return Arrays.equals(array, otherFloatArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Long} instances into a new array of
+ * primitive longs.
+ *
+ * @param collection a collection of {@code Long} objects
+ * @return an array containing the same longs as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static long[] toLongArray(Collection<Long> collection) {
+ int counter = 0;
+ long[] array = new long[collection.size()];
+ for (Long x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Long> asList(long[] backingArray) {
+ return new LongArray(backingArray);
+ }
+
+ private static class LongArray extends PrimitiveArray<Long> {
+ final long[] array;
+
+ LongArray(long[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Long get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Long set(int index, Long element) {
+ Long oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof LongArray) {
+ LongArray otherLongArray = (LongArray) o;
+ return Arrays.equals(array, otherLongArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Character} instances into a new array of
+ * primitive chars.
+ *
+ * @param collection a collection of {@code Character} objects
+ * @return an array containing the same chars as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static char[] toCharArray(Collection<Character> collection) {
+ int counter = 0;
+ char[] array = new char[collection.size()];
+ for (Character x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Character> asList(char[] backingArray) {
+ return new CharacterArray(backingArray);
+ }
+
+ private static class CharacterArray extends PrimitiveArray<Character> {
+ final char[] array;
+
+ CharacterArray(char[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Character get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Character set(int index, Character element) {
+ Character oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof CharacterArray) {
+ CharacterArray otherCharArray = (CharacterArray) o;
+ return Arrays.equals(array, otherCharArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Boolean} instances into a new array of
+ * primitive booleans.
+ *
+ * @param collection a collection of {@code Booleans} objects
+ * @return an array containing the same booleans as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static boolean[] toBooleanArray(Collection<Boolean> collection) {
+ int counter = 0;
+ boolean[] array = new boolean[collection.size()];
+ for (Boolean x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Boolean> asList(boolean[] backingArray) {
+ return new BooleanArray(backingArray);
+ }
+
+ private static class BooleanArray extends PrimitiveArray<Boolean> {
+ final boolean[] array;
+
+ BooleanArray(boolean[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Boolean get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Boolean set(int index, Boolean element) {
+ Boolean oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof BooleanArray) {
+ BooleanArray otherBoolArray = (BooleanArray) o;
+ return Arrays.equals(array, otherBoolArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Converts a collection of {@code Byte} instances into a new array of
+ * primitive bytes.
+ *
+ * @param collection a collection of {@code Byte} objects
+ * @return an array containing the same bytes as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * are null
+ */
+ public static byte[] toByteArray(Collection<Byte> collection) {
+ int counter = 0;
+ byte[] array = new byte[collection.size()];
+ for (Byte x : collection) {
+ array[counter++] = x;
+ }
+ return array;
+ }
+
+ /**
+ * Returns a fixed-size list backed by the specified array, similar to {@link
+ * Arrays#asList}. The only additional restriction of the returned list is
+ * that {@code null} cannot be assigned to any element via {@link
+ * List#set(int,Object)} or {@link ListIterator#set}.
+ *
+ * @param backingArray the array to back the list
+ * @return a list view of the array
+ */
+ public static List<Byte> asList(byte[] backingArray) {
+ return new ByteArray(backingArray);
+ }
+
+ private static class ByteArray extends PrimitiveArray<Byte> {
+ final byte[] array;
+
+ ByteArray(byte[] array) {
+ this.array = checkNotNull(array);
+ }
+
+ @Override public Byte get(int index) {
+ return array[index];
+ }
+
+ @Override public int size() {
+ return array.length;
+ }
+
+ @Override public Byte set(int index, Byte element) {
+ Byte oldValue = array[index];
+ array[index] = element;
+ return oldValue;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof ByteArray) {
+ ByteArray otherByteArray = (ByteArray) o;
+ return Arrays.equals(array, otherByteArray.array);
+ }
+ return super.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return Arrays.hashCode(array);
+ }
+
+ @Override public String toString() {
+ return Arrays.toString(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ReferenceMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ReferenceMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/ReferenceMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,705 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.FinalizableSoftReference;
+import org.richfaces.collections.base.FinalizableWeakReference;
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import org.richfaces.collections.base.ReferenceType;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.ref.Reference;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A {@code ConcurrentMap} implementation that internally utilizes your choice
+ * of strong, soft or weak references for its keys and for its values. As soon
+ * as any key or value is reclaimed by the garbage collector, the corresponding
+ * entry automatically disappears from the map.
+ *
+ * <p>All nine possible combinations of reference types are supported, although
+ * using strong keys with strong values provides no benefit over using a {@code
+ * Map} or {@code ConcurrentMap} directly. This implementation does not permit
+ * null keys or values.
+ *
+ * <p><b>Note:</b> because garbage collection happens concurrently to your
+ * program, it follows that this map is always subject to concurrent
+ * modifications, whether or not the caller exposes it to multiple application
+ * threads. The usual caveats about the reliability of methods such as {@link
+ * #size} and {@link Map#equals} apply; for example, {@link #size} may be
+ * observed to remain unchanged for a short time after an entry was reclaimed.
+ *
+ * <p>To determine equality to a key, this implementation uses
+ * {@link Object#equals} for strong references, and identity-based equality for
+ * soft and weak references. In other words, for a map with weak or soft key
+ * references, {@link #get} returns {@code null} when passed an object that
+ * equals a map key, but isn't the same instance. This behavior is similar to
+ * the way {@link IdentityHashMap} handles key lookups. However, to determine
+ * value equality, as occurs when {@link #containsValue} is called, the
+ * {@code ReferenceMap} always uses {@code equals}, regardless of the value
+ * reference type.
+ *
+ * <p><b>Note:</b> {@code new ReferenceMap(WEAK, STRONG)} is very nearly a
+ * drop-in replacement for {@link WeakHashMap}, but improves upon this by using
+ * only identity-based equality for keys. When possible, {@code ReferenceMap}
+ * should be preferred over the JDK collection, for its concurrency and greater
+ * flexibility.
+ *
+ * <p>Though this class implements {@link Serializable}, serializing reference
+ * maps with weak or soft references leads to unpredictable results.
+ *
+ * @author Bob Lee
+ * @author Kevin Bourrillion
+ */
+public final class ReferenceMap<K, V> extends AbstractMap<K, V>
+ implements ConcurrentMap<K, V>, Serializable {
+ private final ReferenceStrategy keyStrategy;
+ private final ReferenceStrategy valueStrategy;
+
+ /*
+ * The keys in this map are either of type K, SoftReference<K>, or
+ * WeakReference<K>, depending on the chosen keyReferenceType; and likewise
+ * for the values.
+ */
+ private transient ConcurrentMap<Object, Object> delegate;
+
+ /**
+ * Constructs an empty instance, using the given reference types for keys and
+ * values.
+ */
+ public ReferenceMap(
+ ReferenceType keyReferenceType, ReferenceType valueReferenceType) {
+ this(keyReferenceType, valueReferenceType,
+ new ConcurrentHashMap<Object, Object>());
+ }
+
+ /**
+ * Constructs an empty instance, using the given backing map and the given
+ * reference types for keys and values.
+ */
+ public ReferenceMap(ReferenceType keyReferenceType, ReferenceType
+ valueReferenceType, ConcurrentMap<Object, Object> backingMap) {
+ checkArgument(keyReferenceType != ReferenceType.PHANTOM,
+ "Phantom references are not supported.");
+ checkArgument(valueReferenceType != ReferenceType.PHANTOM,
+ "Phantom references are not supported.");
+ checkArgument(backingMap.isEmpty(), "The backing map must be empty.");
+
+ keyStrategy = ReferenceStrategy.forType(keyReferenceType);
+ valueStrategy = ReferenceStrategy.forType(valueReferenceType);
+ delegate = backingMap;
+ }
+
+ /*
+ * Specifying Javadoc for many classes so the AbstractMap Javadoc, which
+ * includes incorrect implementation details, is not displayed.
+ */
+
+ // Query Operations
+
+ /**
+ * Returns the number of key-value mappings in this map.
+ */
+ @Override public int size() {
+ return delegate.size();
+ }
+
+ /**
+ * Returns {@code true} if this map contains no key-value mappings.
+ */
+ @Override public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ /**
+ * Returns {@code true} if this map contains a mapping for the specified key.
+ */
+ @Override public boolean containsKey(Object key) {
+ Object keyDummy = keyStrategy.getDummyFor(key);
+ return delegate.containsKey(keyDummy);
+ }
+
+ /**
+ * Returns {@code true} if this map maps one or more keys to the specified
+ * value.
+ */
+ @Override public boolean containsValue(Object value) {
+ checkNotNull(value);
+ for (Object valueReference : delegate.values()) {
+ if (value.equals(dereferenceValue(valueReference))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped, or {@code null} if
+ * this map contains no mapping for the key.
+ */
+ @Override public V get(Object key) {
+ Object keyDummy = keyStrategy.getDummyFor(key);
+ Object valueReference = delegate.get(keyDummy);
+ return dereferenceValue(valueReference);
+ }
+
+ // Modification Operations
+
+ /**
+ * Associates the specified value with the specified key in this map.
+ */
+ @Override public V put(K key, V value) {
+ Object keyReference = referenceKey(key);
+ Object valueReference = referenceValue(keyReference, value);
+ return dereferenceValue(delegate.put(keyReference, valueReference));
+ }
+
+ public V putIfAbsent(K key, V value) {
+ Object keyReference = referenceKey(key);
+ Object valueReference = referenceValue(keyReference, value);
+
+ Object existingValueReference;
+ V existingValue;
+ do {
+ existingValueReference
+ = delegate.putIfAbsent(keyReference, valueReference);
+ existingValue = dereferenceValue(existingValueReference);
+ } while (isPartiallyReclaimed(existingValueReference, existingValue));
+
+ return existingValue;
+ }
+
+ public V replace(K key, V value) {
+ Object keyReference = referenceKey(key);
+ Object valueReference = referenceValue(keyReference, value);
+
+ // Ensure that the existing value is not collected.
+ do {
+ Object existingValueReference;
+ V existingValue;
+ do {
+ existingValueReference = delegate.get(keyReference);
+
+ /*
+ * This method as a side-effect will proactively call
+ * finalizeReference() as necessary, which prevents this loop from
+ * spinning for a long time.
+ */
+ existingValue = dereferenceValue(existingValueReference);
+ } while (isPartiallyReclaimed(existingValueReference, existingValue));
+
+ if (existingValueReference == null) {
+ return null; // nothing to replace
+ }
+
+ if (delegate.replace(
+ keyReference, existingValueReference, valueReference)) {
+ // existingValue didn't expire since we still have a reference to it
+ return existingValue;
+ }
+ } while (true);
+ }
+
+ public boolean replace(K key, V oldValue, V newValue) {
+ /*
+ * It's surprising how much simpler this, the "more-discriminating" form of
+ * replace(), is to implement than the other, "less-discriminating" form.
+ * The difference is that, because we have a strong reference to
+ * 'oldValue', we know that it can't have been garbage collected and so we
+ * can skip all the logic that handles that case.
+ */
+ Object keyReference = referenceKey(key);
+ Object oldValueDummy = valueStrategy.getDummyFor(oldValue);
+ Object newValueReference = referenceValue(keyReference, newValue);
+ return delegate.replace(keyReference, oldValueDummy, newValueReference);
+ }
+
+ /**
+ * Returns {@code true} if the specified value reference has been garbage
+ * collected. The value behind the reference is also passed in, rather than
+ * queried inside this method, to ensure that the return statement of this
+ * method will still hold true after it has returned (that is, a value
+ * reference exists outside of this method which will prevent that value from
+ * being garbage collected). A {@code false} result may indicate either that
+ * the value has been fully reclaimed, or that it has not been reclaimed at
+ * all.
+ *
+ * @param valueReference the value reference to be tested
+ * @param value the object referenced by {@code valueReference}
+ * @return {@code true} if {@code valueReference} is non-null and {@code
+ * value} is null
+ */
+ private static boolean isPartiallyReclaimed(
+ Object valueReference, Object value) {
+ return (valueReference != null) && (value == null);
+ }
+
+ /**
+ * Removes the mapping for a key from this map if it is present.
+ */
+ @Override public V remove(Object key) {
+ Object keyDummy = keyStrategy.getDummyFor(key);
+ Object valueReference = delegate.remove(keyDummy);
+ return dereferenceValue(valueReference);
+ }
+
+ public boolean remove(Object key, Object value) {
+ Object keyDummy = keyStrategy.getDummyFor(key);
+ Object valueDummy = valueStrategy.getDummyFor(value);
+ return delegate.remove(keyDummy, valueDummy);
+ }
+
+ // Bulk Operations
+
+ // Inherit putAll() from AbstractMap
+
+ /**
+ * Removes all of the mappings from this map.
+ */
+ @Override public void clear() {
+ delegate.clear();
+ }
+
+ // Views
+
+ // Inherit keySet() and values() from AbstractMap
+
+ private transient EntrySet entrySet;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p><b>Note:</b> Regardless of the choice of key and value reference types,
+ * an entry in the entry set always has strong references to both key and
+ * value. You should avoid any lingering strong references to {@code Entry}
+ * objects.
+ */
+ @Override public Set<Map.Entry<K, V>> entrySet() {
+ EntrySet es = entrySet;
+ return (es == null) ? (entrySet = new EntrySet()) : es;
+ }
+
+ private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+ @Override public int size() {
+ return ReferenceMap.this.size();
+ }
+
+ @Override public boolean isEmpty() {
+ return ReferenceMap.this.isEmpty();
+ }
+
+ @Override public boolean contains(Object object) {
+ checkNotNull(object);
+ if (!(object instanceof Map.Entry<?, ?>)) {
+ return false;
+ }
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+ Object key = entry.getKey();
+ Object value = entry.getValue();
+ return key != null && value != null && value.equals(get(key));
+ }
+
+ @Override public Iterator<Map.Entry<K, V>> iterator() {
+ return new EntryIterator();
+ }
+
+ /*
+ * Note: the superclass toArray() methods assume that size() gives a correct
+ * answer, which ours does not.
+ */
+
+ @Override public Object[] toArray() {
+ return snapshot().toArray();
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ checkNotNull(array);
+ return snapshot().toArray(array);
+ }
+
+ /*
+ * We'd love to use 'new ArrayList(this)' or 'list.addAll(this)', but either
+ * of these would recurse back to us again!
+ */
+ private List<Map.Entry<K, V>> snapshot() {
+ List<Map.Entry<K, V>> list = Lists.newArrayListWithExpectedSize(size());
+ for (Map.Entry<K, V> entry : this) {
+ list.add(entry);
+ }
+ return list;
+ }
+
+ @Override public boolean remove(Object object) {
+ checkNotNull(object);
+ if (object instanceof Map.Entry<?, ?>) {
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+ return ReferenceMap.this.remove(entry.getKey(), entry.getValue());
+ }
+ return false;
+ }
+
+ @Override public void clear() {
+ ReferenceMap.this.clear();
+ }
+ }
+
+ private class EntryIterator extends AbstractRemovableIterator<Map.Entry<K, V>>
+ {
+ Iterator<Map.Entry<Object, Object>> delegateEntries
+ = delegate.entrySet().iterator();
+
+ @Override protected Map.Entry<K, V> computeNext() {
+ while (delegateEntries.hasNext()) {
+ Map.Entry<Object, Object> entry = delegateEntries.next();
+ Object reference = entry.getKey();
+
+ @SuppressWarnings("unchecked")
+ final K key = (K) keyStrategy.dereferenceKey(reference);
+
+ if (key != null) {
+ final V value = dereferenceValue(entry.getValue());
+ if (value != null) {
+ return new AbstractMapEntry<K, V>() {
+ V currentValue = value;
+ @Override public K getKey() {
+ return key;
+ }
+ @Override public V getValue() {
+ return currentValue;
+ }
+ @Override public V setValue(V newValue) {
+ put(key, newValue);
+ try {
+ return currentValue;
+ } finally {
+ currentValue = newValue;
+ }
+ }
+ };
+ }
+ }
+ // Otherwise, skip over this partially-GC'ed entry.
+ }
+ return endOfData();
+ }
+
+ /*
+ * On a typical Map this would produce a ConcurrentModificationException,
+ * but we're using a ConcurrentMap, which of course has no problem.
+ */
+ @Override public void remove(Map.Entry<K, V> entry) {
+ ReferenceMap.this.remove(entry.getKey(), entry.getValue());
+ }
+ }
+
+ // Serialization
+
+ /*
+ * "Override" default serialization so that we serialize the wrapped values
+ * themselves (of type K and V), since serializing References would be absurd.
+ */
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject(); // referenceType fields
+ out.writeInt(size());
+ for (Map.Entry<K, V> entry : entrySet()) {
+ out.writeObject(entry.getKey());
+ out.writeObject(entry.getValue());
+ }
+ out.writeObject(null);
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ in.defaultReadObject(); // sets the referenceType fields
+ int approximateSize = in.readInt();
+ delegate = new ConcurrentHashMap<Object, Object>(
+ Maps.capacity(approximateSize));
+ while (true) {
+ @SuppressWarnings("unchecked") // see writeObject()
+ K key = (K) in.readObject();
+ if (key == null) {
+ break;
+ }
+ @SuppressWarnings("unchecked") // see writeObject()
+ V value = (V) in.readObject();
+ put(key, value);
+ }
+ }
+
+ // The rest of the file is all private machinery
+
+ private enum ReferenceStrategy {
+ DIRECT {
+ @Override Object referenceKey(ReferenceMap<?, ?> map, Object key) {
+ return key;
+ }
+ @Override Object referenceValue(
+ ReferenceMap<?, ?> map, Object keyReference, Object value) {
+ return value;
+ }
+ @Override Object dereferenceKey(Object reference) {
+ return reference;
+ }
+ @Override Object dereferenceValue(Object object) {
+ return object;
+ }
+ @Override Object getDummyFor(Object object) {
+ return checkNotNull(object);
+ }
+ },
+
+ WRAP_IN_SOFT {
+ @Override Object referenceKey(ReferenceMap<?, ?> map, Object key) {
+ return map.new SoftKeyReference(key);
+ }
+ @Override Object referenceValue(
+ ReferenceMap<?, ?> map, Object keyReference, Object value) {
+ return map.new SoftValueReference(keyReference, value);
+ }
+ },
+
+ WRAP_IN_WEAK {
+ @Override Object referenceKey(ReferenceMap<?, ?> map, Object key) {
+ return map.new WeakKeyReference(key);
+ }
+ @Override Object referenceValue(
+ ReferenceMap<?, ?> map, Object keyReference, Object value) {
+ return map.new WeakValueReference(keyReference, value);
+ }
+ };
+
+ abstract Object referenceKey(ReferenceMap<?, ?> map, Object key);
+
+ abstract Object referenceValue(
+ ReferenceMap<?, ?> map, Object keyReference, Object value);
+
+ Object dereferenceKey(Object reference) {
+ return ((Reference<?>) reference).get();
+ }
+
+ Object dereferenceValue(Object object) {
+ InternalReference reference = (InternalReference) object;
+ Object value = reference.get();
+
+ /*
+ * It's important that we proactively try to finalize the referent, rather
+ * rather than waiting on the queue, in particular because of the
+ * do/while loop in replace().
+ */
+ if (value == null) {
+ reference.finalizeReferent(); // The old value was garbage collected.
+ }
+ return value;
+ }
+
+ Object getDummyFor(Object object) {
+ return new DummyReference(checkNotNull(object));
+ }
+
+ static ReferenceStrategy forType(ReferenceType type) {
+ switch (checkNotNull(type)) {
+ case STRONG:
+ return ReferenceStrategy.DIRECT;
+ case SOFT:
+ return ReferenceStrategy.WRAP_IN_SOFT;
+ case WEAK:
+ return ReferenceStrategy.WRAP_IN_WEAK;
+ default:
+ throw new AssertionError();
+ }
+ }
+ }
+
+ /*
+ * Marker interface to differentiate external and internal references. Also
+ * duplicates finalizeReferent() and Reference.get() for internal use.
+ */
+ private interface InternalReference {
+ void finalizeReferent();
+ Object get();
+ }
+
+ private class SoftKeyReference extends FinalizableSoftReference<Object>
+ implements InternalReference {
+ final int hashCode;
+
+ SoftKeyReference(Object key) {
+ super(key);
+ hashCode = System.identityHashCode(key);
+ }
+ public void finalizeReferent() {
+ delegate.remove(this);
+ }
+ @Override public int hashCode() {
+ return hashCode;
+ }
+ @Override public boolean equals(Object object) {
+ return referenceEquals(this, object);
+ }
+ }
+
+ private class SoftValueReference extends FinalizableSoftReference<Object>
+ implements InternalReference {
+ final Object keyReference;
+
+ SoftValueReference(Object keyReference, Object value) {
+ super(value);
+ this.keyReference = keyReference;
+ }
+ public void finalizeReferent() {
+ delegate.remove(keyReference, this);
+ }
+ @Override public int hashCode() {
+ // It's hard to define a useful hash code, so we're careful not to use it.
+ throw new AssertionError("don't hash me");
+ }
+ @Override public boolean equals(Object obj) {
+ return referenceEquals(this, obj);
+ }
+ }
+
+ /*
+ * WeakKeyReference/WeakValueReference are absolutely identical to
+ * SoftKeyReference/SoftValueReference except for which classes they extend.
+ */
+
+ private class WeakKeyReference extends FinalizableWeakReference<Object>
+ implements InternalReference {
+ final int hashCode;
+
+ WeakKeyReference(Object key) {
+ super(key);
+ hashCode = System.identityHashCode(key);
+ }
+ public void finalizeReferent() {
+ delegate.remove(this);
+ }
+ @Override public int hashCode() {
+ return hashCode;
+ }
+ @Override public boolean equals(Object object) {
+ return referenceEquals(this, object);
+ }
+ }
+
+ private class WeakValueReference extends FinalizableWeakReference<Object>
+ implements InternalReference {
+ final Object keyReference;
+
+ WeakValueReference(Object keyReference, Object value) {
+ super(value);
+ this.keyReference = keyReference;
+ }
+ public void finalizeReferent() {
+ delegate.remove(keyReference, this);
+ }
+ @Override public int hashCode() {
+ // It's hard to define a useful hash code, so we're careful not to use it.
+ throw new AssertionError("don't hash me");
+ }
+ @Override public boolean equals(Object obj) {
+ return referenceEquals(this, obj);
+ }
+ }
+
+ /*
+ * A short-lived object that is contrived for the purpose of passing to
+ * methods of the backing map such as get(), remove(), containsKey(), and
+ * replace() (all parameters but the last). That is, it's an object suitable
+ * only for use with the backing map, and only for _comparison_ purposes. This
+ * is a hack that lets us compare keys and values to referenced keys and
+ * values without creating more references.
+ */
+ private static class DummyReference {
+ final Object wrapped;
+ DummyReference(Object wrapped) {
+ this.wrapped = wrapped;
+ }
+ Object unwrap() {
+ return wrapped;
+ }
+ @Override public int hashCode() {
+ return System.identityHashCode(wrapped);
+ }
+ @Override public boolean equals(Object object) {
+ return object.equals(this); // Defer to the reference's equals() logic.
+ }
+ }
+
+ /*
+ * Tests weak and soft references for identity equality. Compares references
+ * to other references and wrappers. If o is a reference, this returns true if
+ * r == o or if r and o reference the same non-null object. If o is a wrapper,
+ * this returns true if r's referent is identical to the wrapped object.
+ */
+ private static boolean referenceEquals(Reference<?> reference, Object object)
+ {
+ // Are they the same reference? Used in cleanup.
+ if (object == reference) {
+ return true;
+ }
+ if (object instanceof InternalReference) {
+ /*
+ * Do they reference identical values? Used in conditional puts. We can
+ * assume it's of type InternalReference now, as no one outside
+ * ReferenceMap can be invoking equals().
+ */
+ Object referent = ((InternalReference) object).get();
+ return referent != null && referent == reference.get();
+ }
+
+ // Is the wrapped object identical to the referent? Used in lookups.
+ return ((DummyReference) object).unwrap() == reference.get();
+ }
+
+ private Object referenceKey(K key) {
+ return keyStrategy.referenceKey(this, checkNotNull(key));
+ }
+
+ private Object referenceValue(Object keyReference, V value) {
+ return valueStrategy.referenceValue(
+ this, keyReference, checkNotNull(value));
+ }
+
+ /*
+ * Converts a reference to a value. Do not call this method without being
+ * certain that the object is a reference to a value type (V).
+ */
+ @SuppressWarnings("unchecked")
+ private V dereferenceValue(Object object) {
+ if (object == null) {
+ return null;
+ }
+ return (V) valueStrategy.dereferenceValue(object);
+ }
+
+ private static final long serialVersionUID = 0L;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Serialization.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Serialization.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Serialization.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Provides static method for serializing collection classes.
+ *
+ * @author Jared Levy
+ */
+public final class Serialization {
+ private Serialization() {}
+
+ /**
+ * Stores the contents of a map in an output stream, as part of serialization.
+ * It does not support concurrent maps whose content may change while the
+ * method is running.
+ *
+ * <p>The serialized output consists of the number of entries, first key,
+ * first value, second key, second value, and so on.
+ */
+ public static <K, V> void writeMap(Map<K, V> map, ObjectOutputStream stream)
+ throws IOException {
+ stream.writeInt(map.size());
+ for (Map.Entry<K, V> entry : map.entrySet()) {
+ stream.writeObject(entry.getKey());
+ stream.writeObject(entry.getValue());
+ }
+ }
+
+ /**
+ * Populates a map by reading an input stream, as part of deserialization.
+ * See {@link #writeMap} for the data format.
+ */
+ public static <K, V> void populateMap(Map<K, V> map, ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ int size = stream.readInt();
+ for (int i = 0; i < size; i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMap
+ K key = (K) stream.readObject();
+ @SuppressWarnings("unchecked") // reading data stored by writeMap
+ V value = (V) stream.readObject();
+ map.put(key, value);
+ }
+ }
+ /**
+ * Stores the contents of a multiset in an output stream, as part of
+ * serialization. It does not support concurrent multisets whose content may
+ * change while the method is running.
+ *
+ * <p>The serialized output consists of the number of distinct elements, the
+ * first element, its count, the second element, its count, and so on.
+ */
+ public static <E> void writeMultiset(
+ Multiset<E> multiset, ObjectOutputStream stream) throws IOException {
+ int entryCount = multiset.entrySet().size();
+ stream.writeInt(entryCount);
+ for (Multiset.Entry<E> entry : multiset.entrySet()) {
+ stream.writeObject(entry.getElement());
+ stream.writeInt(entry.getCount());
+ }
+ }
+
+ /**
+ * Populates a multiset by reading an input stream, as part of
+ * deserialization. See {@link #writeMultiset} for the data format.
+ */
+ public static <E> void populateMultiset(
+ Multiset<E> multiset, ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ int entryCount = stream.readInt();
+ for (int i = 0; i < entryCount; i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMultiset
+ E element = (E) stream.readObject();
+ int count = stream.readInt();
+ multiset.add(element, count);
+ }
+ }
+
+ /**
+ * Stores the contents of a multimap in an output stream, as part of
+ * serialization. It does not support concurrent multimaps whose content may
+ * change while the method is running. The {@link Multimap#asMap} view
+ * determines the ordering in which data is written to the stream.
+ *
+ * <p>The serialized output consists of the number of distinct keys, and then
+ * for each distinct key: the key, the number of values for that key, and the
+ * key's values.
+ */
+ public static <K, V> void writeMultimap(
+ Multimap<K, V> multimap, ObjectOutputStream stream) throws IOException {
+ stream.writeInt(multimap.asMap().size());
+ for (Map.Entry<K, Collection<V>> entry : multimap.asMap().entrySet()) {
+ stream.writeObject(entry.getKey());
+ stream.writeInt(entry.getValue().size());
+ for (V value : entry.getValue()) {
+ stream.writeObject(value);
+ }
+ }
+ }
+
+ /**
+ * Populates a multimap by reading an input stream, as part of
+ * deserialization. See {@link #writeMultimap} for the data format.
+ */
+ public static <K, V> void populateMultimap(
+ Multimap<K, V> multimap, ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ int keyCount = stream.readInt();
+ for (int i = 0; i < keyCount; i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMultimap
+ K key = (K) stream.readObject();
+ Collection<V> values = multimap.get(key);
+ int valueCount = stream.readInt();
+ for (int j = 0; j < valueCount; j++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeMultimap
+ V value = (V) stream.readObject();
+ values.add(value);
+ }
+ }
+ }
+
+ /**
+ * Updates the value of a final field, to support field initialization during
+ * deserialization.
+ *
+ * @param clazz the class in which the field is declared
+ * @param instance the instance containing the field to be updated
+ * @param fieldName the name of the field to update
+ * @param value the value to store in the field
+ * @throws NoSuchFieldException if no field has the specified name
+ * @throws SecurityException if a security manager denies the request
+ * @throws IllegalArgumentException if the value cannot be converted to the
+ * type of the field
+ */
+ public static <T> void setFinalField(
+ Class<T> clazz, T instance, String fieldName, Object value)
+ throws SecurityException, NoSuchFieldException {
+ Field field = clazz.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ try {
+ field.set(instance, value);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError(
+ "Field should be accessible after setAccessible(true) call: "
+ + e.getMessage());
+ }
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SetMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SetMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SetMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A {@code Multimap} that cannot hold duplicate key-value pairs. Adding a
+ * key-value pair that's already in the multimap has no effect.
+ *
+ * <p>The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods
+ * each return a {@link Set} of values, while {@link #entries} returns a {@code
+ * Set} of map entries. Though the method signature doesn't say so explicitly,
+ * the map returned by {@link #asMap} has {@code Set} values.
+ *
+ * @author Jared Levy
+ */
+public interface SetMultimap<K, V> extends Multimap<K, V> {
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code SetMultimap} has unique values for a given key, this
+ * method returns a {@link Set}, instead of the {@link java.util.Collection}
+ * specified in the {@link Multimap} interface.
+ */
+ Set<V> get(@Nullable K key);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code SetMultimap} has unique values for a given key, this
+ * method returns a {@link Set}, instead of the {@link java.util.Collection}
+ * specified in the {@link Multimap} interface.
+ */
+ Set<V> removeAll(@Nullable Object key);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code SetMultimap} has unique values for a given key, this
+ * method returns a {@link Set}, instead of the {@link java.util.Collection}
+ * specified in the {@link Multimap} interface.
+ *
+ * <p>Any duplicates in {@code values} will be stored in the multimap once.
+ */
+ Set<V> replaceValues(K key, Iterable<? extends V> values);
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code SetMultimap} has unique values for a given key, this
+ * method returns a {@link Set}, instead of the {@link java.util.Collection}
+ * specified in the {@link Multimap} interface.
+ */
+ Set<Map.Entry<K, V>> entries();
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Though the method signature doesn't say so explicitly, the returned map
+ * has {@link Set} values.
+ */
+ Map<K, Collection<V>> asMap();
+
+ /**
+ * Compares the specified object to this multimap for equality.
+ *
+ * <p>Two {@code SetMultimap} instances are equal if, for each key, they
+ * contain the same values. Equality does not depend on the ordering of keys
+ * or values.
+ */
+ boolean equals(@Nullable Object obj);
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Sets.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Sets.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Sets.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,934 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkContentsNotNull;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+import org.richfaces.collections.base.Predicate;
+import org.richfaces.collections.base.Predicates;
+import org.richfaces.collections.base.ReferenceType;
+import org.richfaces.collections.collect.Collections2.FilteredCollection;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Static utility methods pertaining to {@link Set} instances. Also see this
+ * class's counterparts {@link Lists} and {@link Maps}.
+ *
+ * @author Kevin Bourrillion
+ * @author Jared Levy
+ */
+public final class Sets {
+ private Sets() {}
+
+ /**
+ * Returns an immutable set instance containing the given enum elements.
+ * Internally, the returned set will be backed by an {@link EnumSet}. See
+ * {@link ImmutableSet} for a description of immutability. The set is
+ * serializable.
+ *
+ * @param anElement one of the elements the set should contain
+ * @param otherElements the rest of the elements the set should contain
+ * @return an immutable {@code Set} instance containing those elements, minus
+ * duplicates
+ */
+ public static <E extends Enum<E>> Set<E> immutableEnumSet(
+ E anElement, E... otherElements) {
+ return Collections.unmodifiableSet(EnumSet.of(anElement, otherElements));
+ }
+
+ /**
+ * Returns a new {@code EnumSet} instance containing the given elements.
+ * Unlike {@link EnumSet#copyOf(Collection)}, this method does not produce an
+ * exception on an empty collection, and it may be called on any iterable, not
+ * just a {@code Collection}.
+ */
+ public static <E extends Enum<E>> EnumSet<E> newEnumSet(Iterable<E> iterable,
+ Class<E> elementType) {
+ /*
+ * TODO: noneOf() and addAll() will both throw NullPointerExceptions when
+ * appropriate. However, NullPointerTester will fail on this method because
+ * it passes in Class.class instead of an enum type. This means that, when
+ * iterable is null but elementType is not, noneOf() will throw a
+ * ClassCastException before addAll() has a chance to throw a
+ * NullPointerException. NullPointerTester considers this a failure.
+ * Ideally the test would be fixed, but it would require a special case for
+ * Class<E> where E extends Enum. Until that happens (if ever), leave
+ * checkNotNull() here. For now, contemplate the irony that checking
+ * elementType, the problem argument, is harmful, while checking iterable,
+ * the innocent bystander, is effective.
+ */
+ checkNotNull(iterable);
+ EnumSet<E> set = EnumSet.noneOf(elementType);
+ Iterables.addAll(set, iterable);
+ return set;
+ }
+
+ // HashSet
+
+ /**
+ * Creates an empty {@code HashSet} instance.
+ *
+ * <p><b>Note:</b> if {@code E} is an {@link Enum} type, use {@link
+ * EnumSet#noneOf} instead.
+ *
+ * <p><b>Note:</b> if you need an <i>immutable</i> empty Set, use {@link
+ * Collections#emptySet} instead.
+ *
+ * @return a newly created, empty {@code HashSet}
+ */
+ public static <E> HashSet<E> newHashSet() {
+ return new HashSet<E>();
+ }
+
+ /**
+ * Creates a {@code HashSet} instance containing the given elements.
+ *
+ * <p><b>Note:</b> if {@code E} is an {@link Enum} type, use {@link
+ * EnumSet#of(Enum, Enum...)} instead.
+ *
+ * <p><b>Note:</b> if you need an immutable set without nulls, you should use
+ * {@link ImmutableSet#of(Object...)}.
+ *
+ * <p><b>Note:</b> due to a bug in javac 1.5.0_06, we cannot support the
+ * following:
+ *
+ * <p>{@code Set<Base> set = Sets.newHashSet(sub1, sub2);}
+ *
+ * <p>where {@code sub1} and {@code sub2} are references to subtypes of {@code
+ * Base}, not of {@code Base} itself. To get around this, you must use:
+ *
+ * <p>{@code Set<Base> set = Sets.<Base>newHashSet(sub1, sub2);}
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code HashSet} containing those elements (minus
+ * duplicates)
+ */
+ public static <E> HashSet<E> newHashSet(E... elements) {
+ int capacity = Maps.capacity(elements.length);
+ HashSet<E> set = new HashSet<E>(capacity);
+ Collections.addAll(set, elements);
+ return set;
+ }
+
+ /**
+ * Creates an empty {@code HashSet} instance with enough capacity to hold the
+ * specified number of elements without rehashing.
+ *
+ * @param expectedSize the expected size
+ * @return a newly created {@code HashSet}, empty, with enough capacity to
+ * hold {@code expectedSize} elements without rehashing.
+ * @throws IllegalArgumentException if {@code expectedSize} is negative
+ */
+ public static <E> HashSet<E> newHashSetWithExpectedSize(int expectedSize) {
+ return new HashSet<E>(Maps.capacity(expectedSize));
+ }
+
+ /**
+ * Creates a {@code HashSet} instance containing the given elements.
+ *
+ * <p><b>Note:</b> if {@code E} is an {@link Enum} type, use
+ * {@link #newEnumSet(Iterable, Class)} instead.
+ *
+ * <p><b>Note:</b> if you need an immutable set without nulls, you should use
+ * {@link ImmutableSet#copyOf(Iterable)}.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code HashSet} containing those elements (minus
+ * duplicates)
+ */
+ public static <E> HashSet<E> newHashSet(Iterable<? extends E> elements) {
+ if (elements instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<? extends E> collection = (Collection<? extends E>) elements;
+ return new HashSet<E>(collection);
+ } else {
+ return newHashSet(elements.iterator());
+ }
+ }
+
+ /**
+ * Creates a {@code HashSet} instance containing the given elements.
+ *
+ * <p><b>Note:</b> if {@code E} is an {@link Enum} type, you should create an
+ * {@link EnumSet} instead.
+ *
+ * <p><b>Note:</b> if you need an immutable set without nulls, you should use
+ * {@link ImmutableSet}.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code HashSet} containing those elements (minus
+ * duplicates)
+ */
+ public static <E> HashSet<E> newHashSet(Iterator<? extends E> elements) {
+ HashSet<E> set = newHashSet();
+ while (elements.hasNext()) {
+ set.add(elements.next());
+ }
+ return set;
+ }
+
+ // ConcurrentHashSet
+
+ private static <E> Set<E> fixedRemoveAllAndRetainAll(final Set<E> original) {
+ return new ForwardingSet<E>() {
+ @Override protected Set<E> delegate() {
+ return original;
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+ };
+ }
+
+ /**
+ * ConcurrentHashMap wrapper whose views have {@code removeAll(null)} and
+ * {@code retainAll(null)} throw a {@link NullPointerException}.
+ */
+ private static class ForwardingConcurrentMap<K, V>
+ extends ForwardingMap<K, V> implements Serializable {
+ final Map<K, V> delegate;
+
+ ForwardingConcurrentMap() {
+ delegate = new ConcurrentHashMap<K, V>();
+ }
+
+ ForwardingConcurrentMap(int capacity) {
+ delegate = new ConcurrentHashMap<K, V>(capacity);
+ }
+
+ @Override protected Map<K, V> delegate() {
+ return delegate;
+ }
+
+ transient Set<K> keySet;
+
+ @Override public Set<K> keySet() {
+ Set<K> result = keySet;
+ return (result == null)
+ ? keySet = fixedRemoveAllAndRetainAll(delegate().keySet()) : result;
+ }
+
+ static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Creates a thread-safe set backed by a hash map. The set is backed by a
+ * {@link ConcurrentHashMap} instance, and thus carries the same concurrency
+ * guarantees.
+ *
+ * <p>Unlike {@code HashSet}, this class does NOT allow {@code null} to be
+ * used as an element. The set is serializable.
+ *
+ * @return a newly created, empty thread-safe {@code Set}
+ */
+ public static <E> Set<E> newConcurrentHashSet() {
+ Map<E, Boolean> delegate = new ForwardingConcurrentMap<E, Boolean>();
+ return newSetFromMap(delegate);
+ }
+
+ /**
+ * Creates a thread-safe set backed by a hash map and containing the given
+ * elements. The set is backed by a {@link ConcurrentHashMap} instance, and
+ * thus carries the same concurrency guarantees.
+ *
+ * <p>Unlike {@code HashSet}, this class does NOT allow {@code null} to be
+ * used as an element. The set is serializable.
+ *
+ * <p>Please see the notice in {@link #newHashSet(Object...)} about a relevant
+ * javac bug.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created thread-safe {@code Set} containing those elements
+ * (minus duplicates)
+ * @throws NullPointerException if any of the elements is null
+ */
+ public static <E> Set<E> newConcurrentHashSet(E... elements) {
+ int capacity = Maps.capacity(elements.length);
+ Map<E, Boolean> delegate
+ = new ForwardingConcurrentMap<E, Boolean>(capacity);
+ Set<E> set = newSetFromMap(delegate);
+ Collections.addAll(set, elements);
+ return set;
+ }
+
+ /**
+ * Creates a thread-safe set backed by a hash map and containing the given
+ * elements. The set is backed by a {@link ConcurrentHashMap} instance, and
+ * thus carries the same concurrency guarantees.
+ *
+ * <p>Unlike {@code HashSet}, this class does NOT allow {@code null} to be
+ * used as an element. The set is serializable.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created thread-safe {@code Set} containing those elements
+ * (minus duplicates)
+ * @throws NullPointerException if {@code elements} or any of its contents is
+ * null
+ */
+ public static <E> Set<E> newConcurrentHashSet(Iterable<? extends E> elements)
+ {
+ return newConcurrentHashSet(elements.iterator());
+ }
+
+ /**
+ * Creates a thread-safe set backed by a hash map and containing the given
+ * elements. The set is backed by a {@link ConcurrentHashMap} instance, and
+ * thus carries the same concurrency guarantees.
+ *
+ * <p>Unlike {@code HashSet}, this class does NOT allow {@code null} to be
+ * used as an element. The set is serializable.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created thread-safe {@code Set} containing those elements
+ * (minus duplicates)
+ * @throws NullPointerException if {@code elements} or any of its contents is
+ * null
+ */
+ public static <E> Set<E> newConcurrentHashSet(Iterator<? extends E> elements)
+ {
+ Set<E> set = newConcurrentHashSet();
+ while (elements.hasNext()) {
+ set.add(elements.next());
+ }
+ return set;
+ }
+
+ // LinkedHashSet
+
+ /**
+ * Creates an empty {@code LinkedHashSet} instance.
+ *
+ * @return a newly created, empty {@code LinkedHashSet}
+ */
+ public static <E> LinkedHashSet<E> newLinkedHashSet() {
+ return new LinkedHashSet<E>();
+ }
+
+ /**
+ * Creates a {@code LinkedHashSet} instance containing the given elements.
+ *
+ * <p><b>Note:</b> if you need an immutable set without nulls, you should use
+ * {@link ImmutableSet#copyOf(Iterable)}.
+ *
+ * @param elements the elements that the set should contain, in order
+ * @return a newly created {@code LinkedHashSet} containing those elements
+ * (minus duplicates)
+ */
+ public static <E> LinkedHashSet<E> newLinkedHashSet(
+ Iterable<? extends E> elements) {
+ LinkedHashSet<E> set = newLinkedHashSet();
+ Iterables.addAll(set, elements);
+ return set;
+ }
+
+ // TreeSet, without Comparator
+
+ /**
+ * Creates an empty {@code TreeSet} instance sorted by the natural sort
+ * ordering of its elements.
+ *
+ * @return a newly created, empty {@code TreeSet}
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <E extends Comparable> TreeSet<E> newTreeSet() {
+ return new TreeSet<E>();
+ }
+
+ /**
+ * Creates a {@code TreeSet} instance containing the given elements sorted by
+ * their natural ordering.
+ *
+ * <p><b>Note:</b> if you need an immutable sorted set without nulls, you
+ * should use {@link ImmutableSortedSet#of(Comparable...)}.
+ *
+ * <p>Please see the notice in {@link #newHashSet(Object...)} about a relevant
+ * javac bug.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code TreeSet} containing those elements (minus
+ * duplicates)
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <E extends Comparable> TreeSet<E> newTreeSet(E... elements) {
+ TreeSet<E> set = newTreeSet();
+ Collections.addAll(set, elements);
+ return set;
+ }
+
+ /**
+ * Creates a {@code TreeSet} instance containing the given elements sorted by
+ * their natural ordering.
+ *
+ * <p><b>Note:</b> If {@code elements} is a {@code SortedSet} with an explicit
+ * comparator, this method has different behavior than
+ * {@link TreeSet#TreeSet(SortedSet)}, which returns a {@code TreeSet} with
+ * that comparator.
+ *
+ * <p><b>Note:</b> if you need an immutable sorted set without nulls, you
+ * should use {@link ImmutableSortedSet#copyOf(Iterable)}.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code TreeSet} containing those elements (minus
+ * duplicates)
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <E extends Comparable> TreeSet<E> newTreeSet(
+ Iterable<? extends E> elements) {
+ return newTreeSet(elements.iterator());
+ }
+
+ /**
+ * Creates a {@code TreeSet} instance containing the given elements sorted by
+ * their natural ordering.
+ *
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code TreeSet} containing those elements (minus
+ * duplicates)
+ */
+ @SuppressWarnings("unchecked") // allow ungenerified Comparable types
+ public static <E extends Comparable> TreeSet<E> newTreeSet(
+ Iterator<? extends E> elements) {
+ TreeSet<E> set = newTreeSet();
+ while (elements.hasNext()) {
+ set.add(elements.next());
+ }
+ return set;
+ }
+
+ // TreeSet, with Comparator
+
+ /**
+ * Creates an empty {@code TreeSet} instance with the given comparator.
+ *
+ * @param comparator the comparator to use to sort the set
+ * @return a newly created, empty {@code TreeSet}
+ * @throws NullPointerException if {@code comparator} is null
+ */
+ public static <E> TreeSet<E> newTreeSet(Comparator<? super E> comparator) {
+ return new TreeSet<E>(checkNotNull(comparator));
+ }
+
+ /**
+ * Creates a {@code TreeSet} instance containing the given elements sorted by
+ * the given comparator.
+ *
+ * <p><b>Note:</b> if you need an immutable sorted set without nulls, you
+ * should use {@code ImmutableSortedSet.orderedBy(comparator).of(elements)}.
+ *
+ * <p>Please see the notice in {@link #newHashSet(Object...)} about a relevant
+ * javac bug.
+ *
+ * @param comparator the comparator to use to sort the set
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code TreeSet} containing those elements (minus
+ * duplicates)
+ * @throws NullPointerException if {@code comparator} is null
+ */
+ public static <E> TreeSet<E> newTreeSet(
+ Comparator<? super E> comparator, E... elements) {
+ TreeSet<E> set = newTreeSet(comparator);
+ Collections.addAll(set, elements);
+ return set;
+ }
+
+ /**
+ * Creates a {@code TreeSet} instance containing the given elements sorted by
+ * the given comparator.
+ *
+ * <p><b>Note:</b> if you need an immutable sorted set without nulls, you
+ * should use {@code ImmutableSortedSet.orderedBy(comparator).of(elements)}
+ * instead.
+ *
+ * @param comparator the comparator to use to sort the set
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code TreeSet} containing those elements (minus
+ * duplicates)
+ * @throws NullPointerException if {@code comparator} or {@code elements} is
+ * null
+ */
+ public static <E> TreeSet<E> newTreeSet(
+ Comparator<? super E> comparator, Iterable<? extends E> elements) {
+ return newTreeSet(comparator, elements.iterator());
+ }
+
+ /**
+ * Creates a {@code TreeSet} instance containing the given elements sorted by
+ * the given comparator.
+ *
+ * @param comparator the comparator to use to sort the set
+ * @param elements the elements that the set should contain
+ * @return a newly created {@code TreeSet} containing those elements (minus
+ * duplicates)
+ * @throws NullPointerException if {@code comparator} or {@code elements} is
+ * null
+ */
+ public static <E> TreeSet<E> newTreeSet(
+ Comparator<? super E> comparator, Iterator<? extends E> elements) {
+ TreeSet<E> set = newTreeSet(comparator);
+ while (elements.hasNext()) {
+ set.add(elements.next());
+ }
+ return set;
+ }
+
+ /**
+ * Creates an empty {@code Set} that uses identity to determine equality. It
+ * compares object references, instead of calling {@code equals}, to
+ * determine whether a provided object matches an element in the set. For
+ * example, {@code contains} returns {@code false} when passed an object that
+ * equals a set member, but isn't the same instance. This behavior is similar
+ * to the way {@link IdentityHashMap} handles key lookups.
+ *
+ * <p>The {@code referenceType} parameter specifies the kind of reference that
+ * the returned set uses: {@link ReferenceType#STRONG},
+ * {@link ReferenceType#WEAK}, or {@link ReferenceType#SOFT}. The returned set
+ * is thread-safe when the reference type is {@link ReferenceType#WEAK} or
+ * {@link ReferenceType#SOFT}, but not when the reference type is
+ * {@link ReferenceType#STRONG}.
+ *
+ * @throws IllegalArgumentException if {@code referenceType} is
+ * {@link ReferenceType#PHANTOM}
+ */
+ public static <E> Set<E> newIdentityHashSet(ReferenceType referenceType) {
+ Map<E, Boolean> map;
+ if (referenceType == ReferenceType.STRONG) {
+ map = new IdentityHashMap<E, Boolean>();
+ } else {
+ map = new ReferenceMap<E, Boolean>(referenceType, ReferenceType.STRONG);
+ }
+ return newSetFromMap(map);
+ }
+
+ /**
+ * Creates an {@code EnumSet} consisting of all enum values that are not in
+ * the specified collection. If the collection is an {@link EnumSet}, this
+ * method has the same behavior as {@link EnumSet#complementOf}. Otherwise,
+ * the specified collection must contain at least one element, in order to
+ * determine the element type. If the collection could be empty, use
+ * {@link #complementOf(Collection,Class)} instead of this method.
+ *
+ * @param collection the collection whose complement should be stored in the
+ * enum set
+ * @return a new, modifiable {@code EnumSet} containing all values of the enum
+ * that aren't present in the given collection
+ * @throws IllegalArgumentException if {@code collection} is not an
+ * {@code EnumSet} instance and contains no elements
+ */
+ public static <E extends Enum<E>> EnumSet<E> complementOf(
+ Collection<E> collection) {
+ if (collection instanceof EnumSet) {
+ return EnumSet.complementOf((EnumSet<E>) collection);
+ }
+ checkArgument(!collection.isEmpty(),
+ "collection is empty; use the other version of this method");
+ Class<E> type = collection.iterator().next().getDeclaringClass();
+ return makeComplementByHand(collection, type);
+ }
+
+ /**
+ * Creates an {@code EnumSet} consisting of all enum values that are not in
+ * the specified collection. This is equivalent to
+ * {@link EnumSet#complementOf}, but can act on any input collection, as long
+ * as the elements are of enum type.
+ *
+ * @param collection the collection whose complement should be stored in the
+ * {@code EnumSet}
+ * @param type the type of the elements in the set
+ * @return a new, modifiable {@code EnumSet} initially containing all the
+ * values of the enum not present in the given collection
+ */
+ public static <E extends Enum<E>> EnumSet<E> complementOf(
+ Collection<E> collection, Class<E> type) {
+ checkNotNull(collection);
+ return (collection instanceof EnumSet)
+ ? EnumSet.complementOf((EnumSet<E>) collection)
+ : makeComplementByHand(collection, type);
+ }
+
+ private static <E extends Enum<E>> EnumSet<E> makeComplementByHand(
+ Collection<E> collection, Class<E> type) {
+ EnumSet<E> result = EnumSet.allOf(type);
+ result.removeAll(collection);
+ return result;
+ }
+
+ /*
+ * Regarding newSetForMap() and SetFromMap:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+ /**
+ * Returns a set backed by the specified map. The resulting set displays
+ * the same ordering, concurrency, and performance characteristics as the
+ * backing map. In essence, this factory method provides a {@link Set}
+ * implementation corresponding to any {@link Map} implementation. There is no
+ * need to use this method on a {@link Map} implementation that already has a
+ * corresponding {@link Set} implementation (such as {@link HashMap} or
+ * {@link TreeMap}).
+ *
+ * <p>Each method invocation on the set returned by this method results in
+ * exactly one method invocation on the backing map or its <tt>keySet</tt>
+ * view, with one exception. The <tt>addAll</tt> method is implemented as a
+ * sequence of <tt>put</tt> invocations on the backing map.
+ *
+ * <p>The specified map must be empty at the time this method is invoked,
+ * and should not be accessed directly after this method returns. These
+ * conditions are ensured if the map is created empty, passed directly
+ * to this method, and no reference to the map is retained, as illustrated
+ * in the following code fragment:
+ * <pre>
+ * Set<Object> identityHashSet = Sets.newSetFromMap(
+ * new IdentityHashMap<Object, Boolean>()); </pre>
+ *
+ * This method has the same behavior as the JDK 6 method
+ * {@code Collections.newSetFromMap()}. The returned set is serializable if
+ * the backing map is.
+ *
+ * @param map the backing map
+ * @return the set backed by the map
+ * @throws IllegalArgumentException if <tt>map</tt> is not empty
+ */
+ public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
+ return new SetFromMap<E>(map);
+ }
+
+ private static class SetFromMap<E> extends AbstractSet<E>
+ implements Set<E>, Serializable {
+ private final Map<E, Boolean> m; // The backing map
+ private transient Set<E> s; // Its keySet
+
+ SetFromMap(Map<E, Boolean> map) {
+ checkArgument(map.isEmpty(), "Map is non-empty");
+ m = map;
+ s = map.keySet();
+ }
+
+ @Override public void clear() {
+ m.clear();
+ }
+ @Override public int size() {
+ return m.size();
+ }
+ @Override public boolean isEmpty() {
+ return m.isEmpty();
+ }
+ @Override public boolean contains(Object o) {
+ return m.containsKey(o);
+ }
+ @Override public boolean remove(Object o) {
+ return m.remove(o) != null;
+ }
+ @Override public boolean add(E e) {
+ return m.put(e, Boolean.TRUE) == null;
+ }
+ @Override public Iterator<E> iterator() {
+ return s.iterator();
+ }
+ @Override public Object[] toArray() {
+ return s.toArray();
+ }
+ @Override public <T> T[] toArray(T[] a) {
+ return s.toArray(a);
+ }
+ @Override public String toString() {
+ return s.toString();
+ }
+ @Override public int hashCode() {
+ return s.hashCode();
+ }
+ @Override public boolean equals(Object o) {
+ return (o == this) || s.equals(o);
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ return s.containsAll(c);
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return s.removeAll(c);
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return s.retainAll(c);
+ }
+
+ // addAll is the only inherited implementation
+
+ static final long serialVersionUID = 0;
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ s = m.keySet();
+ }
+ }
+
+ /**
+ * An unmodifiable view of a set which may be backed by other sets; this view
+ * will change as the backing sets do. Contains methods to copy the data into
+ * a new set which will then remain stable.
+ */
+ public static abstract class SetView<E> extends AbstractSet<E> {
+ /**
+ * Returns an immutable copy of the current contents of this set view.
+ * Does not support null elements.
+ */
+ public ImmutableSet<E> immutableCopy() {
+ return ImmutableSet.copyOf(this);
+ }
+
+ /**
+ * Copies the current contents of this set view into an existing set. This
+ * method has equivalent behavior to {@code set.addAll(this)}, assuming that
+ * all the sets involved are based on the same notion of equivalence.
+ */
+ // TODO: add wildcard when we get a fixed javac (e.g. openjdk7)
+ public <S extends Set</*? super */E>> S copyInto(S set) {
+ set.addAll(this);
+ return set;
+ }
+ }
+
+ /**
+ * Returns an unmodifiable <b>view</b> of the union of two sets. The returned
+ * set contains all elements that are contained in either backing set.
+ * Iterating over the returned set iterates first over all the elements of
+ * {@code set1}, then over each element of {@code set2}, in order, that is not
+ * contained in {@code set1}.
+ *
+ * <p>Results are undefined if {@code set1} and {@code set2} are sets based on
+ * different equivalence relations (as {@link HashSet}, {@link TreeSet}, and
+ * the {@link Map#keySet} of an {@link java.util.IdentityHashMap} all are).
+ */
+ public static <E> SetView<E> union(
+ final Set<? extends E> set1, final Set<? extends E> set2) {
+ // TODO: check if sorted sets with same comparator?
+ final Set<? extends E> set2minus1 = difference(set2, set1);
+ final Iterable<E> iterable = Iterables.concat(set1, set2minus1);
+
+ return new SetView<E>() {
+ @Override public int size() {
+ return set1.size() + set2minus1.size();
+ }
+ @Override public boolean isEmpty() {
+ return set1.isEmpty() && set2.isEmpty();
+ }
+ @Override public Iterator<E> iterator() {
+ return Iterators.unmodifiableIterator(iterable.iterator());
+ }
+ @Override public boolean contains(Object object) {
+ return set1.contains(object) || set2.contains(object);
+ }
+ @Override public <S extends Set<E>> S copyInto(S set) {
+ set.addAll(set1);
+ set.addAll(set2);
+ return set;
+ }
+ };
+ }
+
+ /**
+ * Returns an unmodifiable <b>view</b> of the intersection of two sets. The
+ * returned set contains all elements that are contained by both backing sets.
+ * The iteration order of the returned set matches that of {@code set1}.
+ *
+ * <p>Results are undefined if {@code set1} and {@code set2} are sets based
+ * on different equivalence relations (as {@code HashSet}, {@code TreeSet},
+ * and the keySet of an {@code IdentityHashMap} all are).
+ */
+ public static <E> SetView<E> intersection(
+ final Set<E> set1, final Set<?> set2) {
+ // TODO: check if sorted sets with same comparator?
+ checkNotNull(set1);
+ final Predicate<Object> inSet2 = Predicates.in(set2);
+ return new SetView<E>() {
+ @Override public Iterator<E> iterator() {
+ return Iterators.filter(set1.iterator(), inSet2);
+ }
+ @Override public int size() {
+ return Iterators.size(iterator());
+ }
+ @Override public boolean isEmpty() {
+ return Collections.disjoint(set1, set2);
+ }
+ @Override public boolean contains(Object object) {
+ return set1.contains(object) && set2.contains(object);
+ }
+ @Override public boolean containsAll(Collection<?> collection) {
+ return set1.containsAll(collection)
+ && set2.containsAll(collection);
+ }
+ };
+ }
+
+ /**
+ * Returns an unmodifiable <b>view</b> of the difference of two sets. The
+ * returned set contains all elements that are contained by {@code set1} and
+ * not contained by {@code set2}. {@code set2} may also contain elements not
+ * present in {@code set1}; these are simply ignored. The iteration order of
+ * the returned set matches that of {@code set1}.
+ *
+ * <p>Results are undefined if {@code set1} and {@code set2} are sets based
+ * on different equivalence relations (as {@code HashSet}, {@code TreeSet},
+ * and the keySet of an {@code IdentityHashMap} all are).
+ */
+ public static <E> SetView<E> difference(
+ final Set<E> set1, final Set<?> set2) {
+ // TODO: check if sorted sets with same comparator?
+ checkNotNull(set1);
+ final Predicate<Object> notInSet2 = Predicates.not(Predicates.in(set2));
+ return new SetView<E>() {
+ @Override public Iterator<E> iterator() {
+ return Iterators.filter(set1.iterator(), notInSet2);
+ }
+ @Override public int size() {
+ return Iterators.size(iterator());
+ }
+ @Override public boolean isEmpty() {
+ return set2.containsAll(set1);
+ }
+ @Override public boolean contains(Object element) {
+ return set1.contains(element) && !set2.contains(element);
+ }
+ @Override public boolean containsAll(Collection<?> collection) {
+ return set1.containsAll(collection)
+ && Collections.disjoint(set2, collection);
+ }
+ };
+ }
+
+ /**
+ * Returns the elements of {@code unfiltered} that satisfy a predicate. The
+ * returned set is a live view of {@code unfiltered}; changes to one affect
+ * the other.
+ *
+ * <p>The resulting set's iterator does not support {@code remove()}, but all
+ * other set methods are supported. The set's {@code add()} and
+ * {@code addAll()} methods throw an {@link IllegalArgumentException} if an
+ * element that doesn't satisfy the predicate is provided. When methods such
+ * as {@code removeAll()} and {@code clear()} are called on the filtered set,
+ * only elements that satisfy the filter will be removed from the underlying
+ * collection.
+ *
+ * <p>The returned set isn't threadsafe or serializable, even if
+ * {@code unfiltered} is.
+ *
+ * <p>Many of the filtered set's methods, such as {@code size()}, iterate
+ * across every element in the underlying set and determine which elements
+ * satisfy the filter. When a live view is <i>not</i> needed, it may be faster
+ * to copy the filtered set and use the copy.
+ *
+ * <p>The {@code clear()}, {@code removeAll()}, and {@code retainAll()}
+ * methods all call {@link Iterator#remove()} on the underlying collection's
+ * iterator. Consequently, methods like the following throw an
+ * {@link UnsupportedOperationException}.
+ * <pre> Sets.filter(Sets.filter(set, predicate1),
+ * predicate2)).clear();</pre>
+ * Instead, call
+ * {@link org.richfaces.collections.base.Predicates#and(Predicate, Predicate)} to
+ * combine the predicates and pass the combined predicate to this method.
+ *
+ */
+ public static <T> Set<T> filter(
+ Set<T> unfiltered, Predicate<? super T> predicate) {
+ return new FilteredSet<T>(unfiltered, predicate);
+ }
+
+ private static class FilteredSet<E> extends FilteredCollection<E>
+ implements Set<E> {
+ FilteredSet(Set<E> unfiltered, Predicate<? super E> predicate) {
+ super(unfiltered, predicate);
+ }
+
+ @Override public boolean equals(Object obj) {
+ return equalsImpl(this, obj);
+ }
+
+ @Override public int hashCode() {
+ return hashCodeImpl(this);
+ }
+ }
+
+ /*
+ * Standard implementations from AbstractSet.
+ */
+
+ /**
+ * Compares the specified object with the specified set for equality. Returns
+ * true if the specified object is also set, the two sets have the same size,
+ * and every member of the set {@code o} is contained in the set {@code s}.
+ *
+ * <p>This method first checks if the object {@code o} is the set {@code s};
+ * if so it returns true. Then, it checks if {@code o} is a set whose size is
+ * identical to the size of {@code s}; if not, it returns false. If so, it
+ * returns {@code s.containsAll((Collection) o)}.
+ *
+ * @param s the set to be compared for equality with the specified object
+ * @param o the object to be compared for equality with the specified set
+ * @return true if the object {@code o} is equal to the set {@code s}
+ * @see java.util.AbstractSet#equals(Object)
+ */
+ static boolean equalsImpl(Set<?> s, Object o) {
+ if (o == s) {
+ return true;
+ }
+ if (!(o instanceof Set)) {
+ return false;
+ }
+ Set<?> os = (Set<?>) o;
+ if (os.size() != s.size()) {
+ return false;
+ }
+ return s.containsAll(os);
+ }
+
+ /**
+ * Calculates and returns the hash code of {@code s}.
+ */
+ static int hashCodeImpl(Set<?> s) {
+ int hashCode = 0;
+ for (Object o : s) {
+ hashCode += o != null ? o.hashCode() : 0;
+ }
+ return hashCode;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SortedSetMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SortedSetMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/SortedSetMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * A {@code SetMultimap} whose set of values for a given key are kept sorted;
+ * that is, they comprise a {@link SortedSet}. It cannot hold duplicate
+ * key-value pairs; adding a key-value pair that's already in the multimap has
+ * no effect. This interface does not specify the ordering of the multimap's
+ * keys.
+ *
+ * <p>The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods
+ * each return a {@link SortedSet} of values, while {@link Multimap#entries()}
+ * returns a {@link Set} of map entries. Though the method signature doesn't say
+ * so explicitly, the map returned by {@link #asMap} has {@code SortedSet}
+ * values.
+ *
+ * @author Jared Levy
+ */
+public interface SortedSetMultimap<K, V> extends SetMultimap<K, V> {
+ /**
+ * Returns a collection view of all values associated with a key. If no
+ * mappings in the multimap have the provided key, an empty collection is
+ * returned.
+ *
+ * <p>Changes to the returned collection will update the underlying multimap,
+ * and vice versa.
+ *
+ * <p>Because a {@code SortedSetMultimap} has unique sorted values for a given
+ * key, this method returns a {@link SortedSet}, instead of the
+ * {@link java.util.Collection} specified in the {@link Multimap} interface.
+ */
+ SortedSet<V> get(@Nullable K key);
+
+ /**
+ * Removes all values associated with a given key.
+ *
+ * <p>Because a {@code SortedSetMultimap} has unique sorted values for a given
+ * key, this method returns a {@link SortedSet}, instead of the
+ * {@link java.util.Collection} specified in the {@link Multimap} interface.
+ */
+ SortedSet<V> removeAll(@Nullable Object key);
+
+ /**
+ * Stores a collection of values with the same key, replacing any existing
+ * values for that key.
+ *
+ * <p>Because a {@code SortedSetMultimap} has unique sorted values for a given
+ * key, this method returns a {@link SortedSet}, instead of the
+ * {@link java.util.Collection} specified in the {@link Multimap} interface.
+ *
+ * <p>Any duplicates in {@code values} will be stored in the multimap once.
+ */
+ SortedSet<V> replaceValues(K key, Iterable<? extends V> values);
+
+ /**
+ * Returns a map view that associates each key with the corresponding values
+ * in the multimap. Changes to the returned map, such as element removal,
+ * will update the underlying multimap. The map never supports
+ * {@code setValue()} on the map entries, {@code put}, or {@code putAll}.
+ *
+ * <p>The collections returned by {@code asMap().get(Object)} have the same
+ * behavior as those returned by {@link #get}.
+ *
+ * <p>Though the method signature doesn't say so explicitly, the returned map
+ * has {@link SortedSet} values.
+ */
+ Map<K, Collection<V>> asMap();
+
+ /**
+ * Returns the comparator that orders the multimap values, with a {@code null}
+ * indicating that natural ordering is used.
+ */
+ Comparator<? super V> valueComparator();
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardBiMap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardBiMap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardBiMap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkState;
+
+import org.richfaces.collections.base.Objects;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A general-purpose bimap implementation using any two backing {@code Map}
+ * instances.
+ *
+ * @author Kevin Bourrillion
+ * @author Mike Bostock
+ */
+class StandardBiMap<K, V> extends ForwardingMap<K, V>
+ implements BiMap<K, V>, Serializable {
+
+ private transient Map<K, V> delegate;
+ private transient StandardBiMap<V, K> inverse;
+
+ /** Package-private constructor for creating a map-backed bimap. */
+ StandardBiMap(Map<K, V> forward, Map<V, K> backward) {
+ setDelegates(forward, backward);
+ }
+
+ /** Private constructor for inverse bimap. */
+ private StandardBiMap(Map<K, V> backward, StandardBiMap<V, K> forward) {
+ delegate = backward;
+ inverse = forward;
+ }
+
+ @Override protected Map<K, V> delegate() {
+ return delegate;
+ }
+
+ /**
+ * Specifies the delegate maps going in each direction. Called by the
+ * constructor and by subclasses during deserialization.
+ */
+ void setDelegates(Map<K, V> forward, Map<V, K> backward) {
+ checkState(delegate == null);
+ checkState(inverse == null);
+ checkArgument(forward.isEmpty());
+ checkArgument(backward.isEmpty());
+ checkArgument(forward != backward);
+ delegate = forward;
+ inverse = new Inverse<V, K>(backward, this);
+ }
+
+ void setInverse(StandardBiMap<V, K> inverse) {
+ this.inverse = inverse;
+ }
+
+ // Query Operations (optimizations)
+
+ @Override public boolean containsValue(Object value) {
+ return inverse.containsKey(value);
+ }
+
+ // Modification Operations
+
+ @Override public V put(K key, V value) {
+ return putInBothMaps(key, value, false);
+ }
+
+ public V forcePut(K key, V value) {
+ return putInBothMaps(key, value, true);
+ }
+
+ private V putInBothMaps(K key, V value, boolean force) {
+ boolean containedKey = containsKey(key);
+ if (containedKey && Objects.equal(value, get(key))) {
+ return value;
+ }
+ if (force) {
+ inverse().remove(value);
+ } else {
+ checkArgument(!containsValue(value), "value already present: %s", value);
+ }
+ V oldValue = delegate.put(key, value);
+ updateInverseMap(key, containedKey, oldValue, value);
+ return oldValue;
+ }
+
+ private void updateInverseMap(
+ K key, boolean containedKey, V oldValue, V newValue) {
+ if (containedKey) {
+ removeFromInverseMap(oldValue);
+ }
+ inverse.delegate.put(newValue, key);
+ }
+
+ @Override public V remove(Object key) {
+ return containsKey(key) ? removeFromBothMaps(key) : null;
+ }
+
+ private V removeFromBothMaps(Object key) {
+ V oldValue = delegate.remove(key);
+ removeFromInverseMap(oldValue);
+ return oldValue;
+ }
+
+ private void removeFromInverseMap(V oldValue) {
+ inverse.delegate.remove(oldValue);
+ }
+
+ // Bulk Operations
+
+ @Override public void putAll(Map<? extends K, ? extends V> map) {
+ for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
+ put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override public void clear() {
+ delegate.clear();
+ inverse.delegate.clear();
+ }
+
+ // Views
+
+ public BiMap<V, K> inverse() {
+ return inverse;
+ }
+
+ private transient volatile Set<K> keySet;
+
+ @Override public Set<K> keySet() {
+ Set<K> result = keySet;
+ return (result == null) ? keySet = new KeySet() : keySet;
+ }
+
+ private class KeySet extends ForwardingSet<K> {
+ @Override protected Set<K> delegate() {
+ return delegate.keySet();
+ }
+
+ @Override public void clear() {
+ StandardBiMap.this.clear();
+ }
+
+ @Override public boolean remove(Object key) {
+ if (!contains(key)) {
+ return false;
+ }
+ removeFromBothMaps(key);
+ return true;
+ }
+
+ @Override public boolean removeAll(Collection<?> keysToRemove) {
+ return Iterators.removeAll(iterator(), keysToRemove);
+ }
+
+ @Override public boolean retainAll(Collection<?> keysToRetain) {
+ return Iterators.retainAll(iterator(), keysToRetain);
+ }
+
+ @Override public Iterator<K> iterator() {
+ final Iterator<Entry<K, V>> iterator = delegate.entrySet().iterator();
+ return new Iterator<K>() {
+ Entry<K, V> entry;
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ public K next() {
+ entry = iterator.next();
+ return entry.getKey();
+ }
+ public void remove() {
+ iterator.remove();
+ removeFromInverseMap(entry.getValue());
+ }
+ };
+ }
+ }
+
+ private transient volatile Set<V> valueSet;
+
+ @Override public Set<V> values() {
+ /*
+ * We can almost reuse the inverse's keySet, except we have to fix the
+ * iteration order so that it is consistent with the forward map.
+ */
+ Set<V> result = valueSet;
+ return (result == null) ? valueSet = new ValueSet() : valueSet;
+ }
+
+ private class ValueSet extends ForwardingSet<V> {
+ final Set<V> valuesDelegate = inverse.keySet();
+
+ @Override protected Set<V> delegate() {
+ return valuesDelegate;
+ }
+
+ @Override public Iterator<V> iterator() {
+ final Iterator<V> iterator = delegate.values().iterator();
+ return new Iterator<V>() {
+ V valueToRemove;
+
+ /*@Override*/ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ /*@Override*/ public V next() {
+ return valueToRemove = iterator.next();
+ }
+
+ /*@Override*/ public void remove() {
+ iterator.remove();
+ removeFromInverseMap(valueToRemove);
+ }
+ };
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+
+ @Override public String toString() {
+ return Iterators.toString(iterator());
+ }
+ }
+
+ private transient volatile Set<Entry<K, V>> entrySet;
+
+ @Override public Set<Entry<K, V>> entrySet() {
+ Set<Entry<K, V>> result = entrySet;
+ return (result == null) ? entrySet = new EntrySet() : entrySet;
+ }
+
+ private class EntrySet extends ForwardingSet<Entry<K, V>> {
+ final Set<Entry<K, V>> esDelegate = delegate.entrySet();
+
+ @Override protected Set<Entry<K, V>> delegate() {
+ return esDelegate;
+ }
+
+ @Override public void clear() {
+ StandardBiMap.this.clear();
+ }
+
+ @Override public boolean remove(Object object) {
+ if (!esDelegate.remove(object)) {
+ return false;
+ }
+ Entry<?, ?> entry = (Entry<?, ?>) object;
+ inverse.delegate.remove(entry.getValue());
+ return true;
+ }
+
+ @Override public Iterator<Entry<K, V>> iterator() {
+ final Iterator<Entry<K, V>> iterator = esDelegate.iterator();
+ return new Iterator<Entry<K, V>>() {
+ Entry<K, V> entry;
+
+ /*@Override*/ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ /*@Override*/ public Entry<K, V> next() {
+ entry = iterator.next();
+ final Entry<K, V> finalEntry = entry;
+
+ return new ForwardingMapEntry<K, V>() {
+ @Override protected Entry<K, V> delegate() {
+ return finalEntry;
+ }
+
+ @Override public V setValue(V value) {
+ // Preconditions keep the map and inverse consistent.
+ checkState(contains(this), "entry no longer in map");
+ // similar to putInBothMaps, but set via entry
+ if (Objects.equal(value, getValue())) {
+ return value;
+ }
+ checkArgument(!containsValue(value),
+ "value already present: %s", value);
+ V oldValue = finalEntry.setValue(value);
+ checkState(Objects.equal(value, get(getKey())),
+ "entry no longer in map");
+ updateInverseMap(getKey(), true, oldValue, value);
+ return oldValue;
+ }
+ };
+ }
+
+ /*@Override*/ public void remove() {
+ iterator.remove();
+ removeFromInverseMap(entry.getValue());
+ }
+ };
+ }
+
+ // See java.util.Collections.CheckedEntrySet for details on attacks.
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+ @Override public boolean contains(Object o) {
+ return Maps.containsEntryImpl(delegate(), o);
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ return Collections2.containsAll(this, c);
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+ }
+
+ /** The inverse of any other {@code StandardBiMap} subclass. */
+ private static class Inverse<K, V> extends StandardBiMap<K, V> {
+ private Inverse(Map<K, V> backward, StandardBiMap<V, K> forward) {
+ super(backward, forward);
+ }
+
+ /*
+ * Serialization stores the forward bimap, the inverse of this inverse.
+ * Deserialization calls inverse() on the forward bimap and returns that
+ * inverse.
+ *
+ * If a bimap and its inverse are serialized together, the deserialized
+ * instances have inverse() methods that return the other.
+ */
+
+ /**
+ * @serialData the forward bimap
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(inverse());
+ }
+
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ setInverse((StandardBiMap<V, K>) stream.readObject());
+ }
+
+ Object readResolve() {
+ return inverse().inverse();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardListMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardListMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardListMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Basic implementation of the {@link ListMultimap} interface. It's a wrapper
+ * around {@link StandardMultimap} that converts the returned collections into
+ * {@code Lists}. The {@link #createCollection} method must return a {@code
+ * List}.
+ *
+ * @author Jared Levy
+ */
+abstract class StandardListMultimap<K, V>
+ extends StandardMultimap<K, V> implements ListMultimap<K, V> {
+ /**
+ * Creates a new multimap that uses the provided map.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ */
+ protected StandardListMultimap(Map<K, Collection<V>> map) {
+ super(map);
+ }
+
+ @Override abstract List<V> createCollection();
+
+ @Override public List<V> get(@Nullable K key) {
+ return (List<V>) super.get(key);
+ }
+
+ @Override public List<V> removeAll(@Nullable Object key) {
+ return (List<V>) super.removeAll(key);
+ }
+
+ @Override public List<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
+ return (List<V>) super.replaceValues(key, values);
+ }
+
+ /**
+ * Stores a key-value pair in the multimap.
+ *
+ * @param key key to store in the multimap
+ * @param value value to store in the multimap
+ * @return {@code true} always
+ */
+ @Override public boolean put(@Nullable K key, @Nullable V value) {
+ return super.put(key, value);
+ }
+
+ /**
+ * Compares the specified object to this multimap for equality.
+ *
+ * <p>Two {@code ListMultimap} instances are equal if, for each key, they
+ * contain the same values in the same order. If the value orderings disagree,
+ * the multimaps will not be considered equal.
+ */
+ @Override public boolean equals(@Nullable Object obj) {
+ return super.equals(obj);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,1442 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkArgument;
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import org.richfaces.collections.base.Nullable;
+import org.richfaces.collections.base.Objects;
+
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.RandomAccess;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+/**
+ * Basic implementation of the {@link Multimap} interface. This class represents
+ * a multimap as a map that associates each key with a collection of values. All
+ * methods of {@link Multimap} are supported, including those specified as
+ * optional in the interface.
+ *
+ * <p>To implement a multimap, a subclass must define the method {@link
+ * #createCollection()}, which creates an empty collection of values for a key.
+ *
+ * <p>The multimap constructor takes a map that has a single entry for each
+ * distinct key. When you insert a key-value pair with a key that isn't already
+ * in the multimap, {@code StandardMultimap} calls {@link #createCollection()}
+ * to create the collection of values for that key. The subclass should not call
+ * {@link #createCollection()} directly, and a new instance should be created
+ * every time the method is called.
+ *
+ * <p>For example, the subclass could pass a {@link java.util.TreeMap} during
+ * construction, and {@link #createCollection()} could return a {@link
+ * java.util.TreeSet}, in which case the multimap's iterators would propagate
+ * through the keys and values in sorted order.
+ *
+ * <p>Keys and values may be null, as long as the underlying collection classes
+ * support null elements.
+ *
+ * <p>The collections created by {@link #createCollection()} may or may not
+ * allow duplicates. If the collection, such as a {@link Set}, does not support
+ * duplicates, an added key-value pair will replace an existing pair with the
+ * same key and value, if such a pair is present. With collections like {@link
+ * List} that allow duplicates, the collection will keep the existing key-value
+ * pairs while adding a new pair.
+ *
+ * <p>This class is not threadsafe when any concurrent operations update the
+ * multimap, even if the underlying map and {@link #createCollection()} method
+ * return threadsafe classes. Concurrent read operations will work correctly. To
+ * allow concurrent update operations, wrap your multimap with a call to {@link
+ * Multimaps#synchronizedMultimap}.
+ *
+ * <p>For serialization to work, the subclass must specify explicit
+ * {@code readObject} and {@code writeObject} methods.
+ *
+ * @author Jared Levy
+ */
+abstract class StandardMultimap<K, V> implements Multimap<K, V>, Serializable {
+ /*
+ * Here's an outline of the overall design.
+ *
+ * The map variable contains the collection of values associated with each
+ * key. When a key-value pair is added to a multimap that didn't previously
+ * contain any values for that key, a new collection generated by
+ * createCollection is added to the map. That same collection instance
+ * remains in the map as long as the multimap has any values for the key. If
+ * all values for the key are removed, the key and collection are removed
+ * from the map.
+ *
+ * The get method returns a WrappedCollection, which decorates the collection
+ * in the map (if the key is present) or an empty collection (if the key is
+ * not present). When the collection delegate in the WrappedCollection is
+ * empty, the multimap may contain subsequently added values for that key. To
+ * handle that situation, the WrappedCollection checks whether map contains
+ * an entry for the provided key, and if so replaces the delegate.
+ */
+
+ private transient Map<K, Collection<V>> map;
+ private transient int totalSize;
+
+ /**
+ * Creates a new multimap that uses the provided map.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ * @throws IllegalArgumentException if {@code map} is not empty
+ */
+ protected StandardMultimap(Map<K, Collection<V>> map) {
+ checkArgument(map.isEmpty());
+ this.map = map;
+ }
+
+ /** Used during deserialization only. */
+ protected void setMap(Map<K, Collection<V>> map) {
+ this.map = map;
+ totalSize = 0;
+ for (Collection<V> values : map.values()) {
+ checkArgument(!values.isEmpty());
+ totalSize += values.size();
+ }
+ }
+
+ /**
+ * Creates the collection of values for a single key.
+ *
+ * <p>Collections with weak, soft, or phantom references are not supported.
+ * Each call to {@code createCollection} should create a new instance.
+ *
+ * <p>The returned collection class determines whether duplicate key-value
+ * pairs are allowed.
+ *
+ * @return an empty collection of values
+ */
+ abstract Collection<V> createCollection();
+
+ /**
+ * Creates the collection of values for an explicitly provided key. By
+ * default, it simply calls {@link #createCollection()}, which is the correct
+ * behavior for most implementations. The {@link LinkedHashMultimap} class
+ * overrides it.
+ *
+ * @param key key to associate with values in the collection
+ * @return an empty collection of values
+ */
+ Collection<V> createCollection(@Nullable K key) {
+ return createCollection();
+ }
+
+ Map<K, Collection<V>> backingMap() {
+ return map;
+ }
+
+ // Query Operations
+
+ public int size() {
+ return totalSize;
+ }
+
+ public boolean isEmpty() {
+ return totalSize == 0;
+ }
+
+ public boolean containsKey(@Nullable Object key) {
+ return map.containsKey(key);
+ }
+
+ public boolean containsValue(@Nullable Object value) {
+ for (Collection<V> collection : map.values()) {
+ if (collection.contains(value)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
+ Collection<V> collection = map.get(key);
+ return collection != null && collection.contains(value);
+ }
+
+ // Modification Operations
+
+ public boolean put(@Nullable K key, @Nullable V value) {
+ Collection<V> collection = getOrCreateCollection(key);
+
+ if (collection.add(value)) {
+ totalSize++;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private Collection<V> getOrCreateCollection(K key) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ collection = createCollection(key);
+ map.put(key, collection);
+ }
+ return collection;
+ }
+
+ public boolean remove(@Nullable Object key, @Nullable Object value) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ return false;
+ }
+
+ boolean changed = collection.remove(value);
+ if (changed) {
+ totalSize--;
+ if (collection.isEmpty()) {
+ map.remove(key);
+ }
+ }
+ return changed;
+ }
+
+ // Bulk Operations
+
+ public boolean putAll(@Nullable K key, Iterable<? extends V> values) {
+ if (!values.iterator().hasNext()) {
+ return false;
+ }
+ Collection<V> collection = getOrCreateCollection(key);
+ int oldSize = collection.size();
+
+ boolean changed = false;
+ if (values instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<? extends V> c = (Collection<? extends V>) values;
+ changed = collection.addAll(c);
+ } else {
+ for (V value : values) {
+ changed |= collection.add(value);
+ }
+ }
+
+ totalSize += (collection.size() - oldSize);
+ return changed;
+ }
+
+ public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ boolean changed = false;
+ for (Map.Entry<? extends K, ? extends V> entry : multimap.entries()) {
+ changed |= put(entry.getKey(), entry.getValue());
+ }
+ return changed;
+ }
+
+ public Collection<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
+ Iterator<? extends V> iterator = values.iterator();
+ if (!iterator.hasNext()) {
+ return removeAll(key);
+ }
+
+ Collection<V> collection = getOrCreateCollection(key);
+ Collection<V> oldValues = createCollection();
+ oldValues.addAll(collection);
+
+ totalSize -= collection.size();
+ collection.clear();
+
+ while (iterator.hasNext()) {
+ if (collection.add(iterator.next())) {
+ totalSize++;
+ }
+ }
+
+ return oldValues;
+ }
+
+ public Collection<V> removeAll(@Nullable Object key) {
+ Collection<V> collection = map.remove(key);
+ Collection<V> output = createCollection();
+
+ if (collection != null) {
+ output.addAll(collection);
+ totalSize -= collection.size();
+ collection.clear();
+ }
+
+ return output;
+ }
+
+ public void clear() {
+ // Clear each collection, to make previously returned collections empty.
+ for (Collection<V> collection : map.values()) {
+ collection.clear();
+ }
+ map.clear();
+ totalSize = 0;
+ }
+
+ // Views
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned collection is not serializable.
+ */
+ public Collection<V> get(@Nullable K key) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ collection = createCollection(key);
+ }
+ return wrapCollection(key, collection);
+ }
+
+ /**
+ * Generates a decorated collection that remains consistent with the values in
+ * the multimap for the provided key. Changes to the multimap may alter the
+ * returned collection, and vice versa.
+ */
+ private Collection<V> wrapCollection(K key, Collection<V> collection) {
+ if (collection instanceof SortedSet) {
+ return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
+ } else if (collection instanceof Set) {
+ return new WrappedSet(key, (Set<V>) collection);
+ } else if (collection instanceof List) {
+ return wrapList(key, (List<V>) collection, null);
+ } else {
+ return new WrappedCollection(key, collection, null);
+ }
+ }
+
+ private List<V> wrapList(K key, List<V> list, WrappedCollection ancestor) {
+ return (list instanceof RandomAccess)
+ ? new RandomAccessWrappedList(key, list, ancestor)
+ : new WrappedList(key, list, ancestor);
+ }
+
+ /**
+ * Collection decorator that stays in sync with the multimap values for a key.
+ * There are two kinds of wrapped collections: full and subcollections. Both
+ * have a delegate pointing to the underlying collection class.
+ *
+ * <p>Full collections, identified by a null ancestor field, contain all
+ * multimap values for a given key. Its delegate is a value in {@link
+ * StandardMultimap#map} whenever the delegate is non-empty. The {@code
+ * refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} methods ensure
+ * that the {@code WrappedCollection} and map remain consistent.
+ *
+ * <p>A subcollection, such as a sublist, contains some of the values for a
+ * given key. Its ancestor field points to the full wrapped collection with
+ * all values for the key. The subcollection {@code refreshIfEmpty}, {@code
+ * removeIfEmpty}, and {@code addToMap} methods call the corresponding methods
+ * of the full wrapped collection.
+ */
+ private class WrappedCollection extends AbstractCollection<V> {
+ final K key;
+ Collection<V> delegate;
+ final WrappedCollection ancestor;
+ final Collection<V> ancestorDelegate;
+
+ WrappedCollection(K key, Collection<V> delegate,
+ WrappedCollection ancestor) {
+ this.key = key;
+ this.delegate = delegate;
+ this.ancestor = ancestor;
+ this.ancestorDelegate
+ = (ancestor == null) ? null : ancestor.getDelegate();
+ }
+
+ /**
+ * If the delegate collection is empty, but the multimap has values for the
+ * key, replace the delegate with the new collection for the key.
+ *
+ * <p>For a subcollection, refresh its ancestor and validate that the
+ * ancestor delegate hasn't changed.
+ */
+ void refreshIfEmpty() {
+ if (ancestor != null) {
+ ancestor.refreshIfEmpty();
+ if (ancestor.getDelegate() != ancestorDelegate) {
+ throw new ConcurrentModificationException();
+ }
+ } else if (delegate.isEmpty()) {
+ Collection<V> newDelegate = map.get(key);
+ if (newDelegate != null) {
+ delegate = newDelegate;
+ }
+ }
+ }
+
+ /**
+ * If collection is empty, remove it from {@code map}. For subcollections,
+ * check whether the ancestor collection is empty.
+ */
+ void removeIfEmpty() {
+ if (ancestor != null) {
+ ancestor.removeIfEmpty();
+ } else if (delegate.isEmpty()) {
+ map.remove(key);
+ }
+ }
+
+ K getKey() {
+ return key;
+ }
+
+ /**
+ * Add the delegate to the map. Other {@code WrappedCollection} methods
+ * should call this method after adding elements to a previously empty
+ * collection.
+ *
+ * <p>Subcollection add the ancestor's delegate instead.
+ */
+ void addToMap() {
+ if (ancestor != null) {
+ ancestor.addToMap();
+ } else {
+ map.put(key, delegate);
+ }
+ }
+
+ @Override public int size() {
+ refreshIfEmpty();
+ return delegate.size();
+ }
+
+ @Override public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ refreshIfEmpty();
+ return delegate.equals(other);
+ }
+
+ @Override public int hashCode() {
+ refreshIfEmpty();
+ return delegate.hashCode();
+ }
+
+ @Override public String toString() {
+ refreshIfEmpty();
+ return delegate.toString();
+ }
+
+ Collection<V> getDelegate() {
+ return delegate;
+ }
+
+ @Override public Iterator<V> iterator() {
+ refreshIfEmpty();
+ return new WrappedIterator();
+ }
+
+ /** Collection iterator for {@code WrappedCollection}. */
+ class WrappedIterator implements Iterator<V> {
+ final Iterator<V> delegateIterator;
+ final Collection<V> originalDelegate = delegate;
+
+ WrappedIterator() {
+ delegateIterator = iteratorOrListIterator(delegate);
+ }
+
+ WrappedIterator(Iterator<V> delegateIterator) {
+ this.delegateIterator = delegateIterator;
+ }
+
+ /**
+ * If the delegate changed since the iterator was created, the iterator is
+ * no longer valid.
+ */
+ void validateIterator() {
+ refreshIfEmpty();
+ if (delegate != originalDelegate) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ public boolean hasNext() {
+ validateIterator();
+ return delegateIterator.hasNext();
+ }
+
+ public V next() {
+ validateIterator();
+ return delegateIterator.next();
+ }
+
+ public void remove() {
+ delegateIterator.remove();
+ totalSize--;
+ removeIfEmpty();
+ }
+
+ Iterator<V> getDelegateIterator() {
+ validateIterator();
+ return delegateIterator;
+ }
+ }
+
+ @Override public boolean add(V value) {
+ refreshIfEmpty();
+ boolean wasEmpty = delegate.isEmpty();
+ boolean changed = delegate.add(value);
+ if (changed) {
+ totalSize++;
+ if (wasEmpty) {
+ addToMap();
+ }
+ }
+ return changed;
+ }
+
+ WrappedCollection getAncestor() {
+ return ancestor;
+ }
+
+ // The following methods are provided for better performance.
+
+ @Override public boolean addAll(Collection<? extends V> collection) {
+ if (collection.isEmpty()) {
+ return false;
+ }
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = delegate.addAll(collection);
+ if (changed) {
+ int newSize = delegate.size();
+ totalSize += (newSize - oldSize);
+ if (oldSize == 0) {
+ addToMap();
+ }
+ }
+ return changed;
+ }
+
+ @Override public boolean contains(Object o) {
+ refreshIfEmpty();
+ return delegate.contains(o);
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ refreshIfEmpty();
+ return delegate.containsAll(c);
+ }
+
+ @Override public void clear() {
+ int oldSize = size(); // calls refreshIfEmpty
+ if (oldSize == 0) {
+ return;
+ }
+ delegate.clear();
+ totalSize -= oldSize;
+ removeIfEmpty(); // maybe shouldn't be removed if this is a sublist
+ }
+
+ @Override public boolean remove(Object o) {
+ refreshIfEmpty();
+ boolean changed = delegate.remove(o);
+ if (changed) {
+ totalSize--;
+ removeIfEmpty();
+ }
+ return changed;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ if (c.isEmpty()) {
+ return false;
+ }
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = delegate.removeAll(c);
+ if (changed) {
+ int newSize = delegate.size();
+ totalSize += (newSize - oldSize);
+ removeIfEmpty();
+ }
+ return changed;
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ checkNotNull(c);
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = delegate.retainAll(c);
+ if (changed) {
+ int newSize = delegate.size();
+ totalSize += (newSize - oldSize);
+ removeIfEmpty();
+ }
+ return changed;
+ }
+ }
+
+ private Iterator<V> iteratorOrListIterator(Collection<V> collection) {
+ return (collection instanceof List)
+ ? ((List<V>) collection).listIterator()
+ : collection.iterator();
+ }
+
+ /** Set decorator that stays in sync with the multimap values for a key. */
+ private class WrappedSet extends WrappedCollection implements Set<V> {
+ WrappedSet(K key, Set<V> delegate) {
+ super(key, delegate, null);
+ }
+ }
+
+ /**
+ * SortedSet decorator that stays in sync with the multimap values for a key.
+ */
+ private class WrappedSortedSet extends WrappedCollection
+ implements SortedSet<V> {
+ WrappedSortedSet(K key, SortedSet<V> delegate, WrappedCollection ancestor) {
+ super(key, delegate, ancestor);
+ }
+
+ SortedSet<V> getSortedSetDelegate() {
+ return (SortedSet<V>) getDelegate();
+ }
+
+ public Comparator<? super V> comparator() {
+ return getSortedSetDelegate().comparator();
+ }
+
+ public V first() {
+ refreshIfEmpty();
+ return getSortedSetDelegate().first();
+ }
+
+ public V last() {
+ refreshIfEmpty();
+ return getSortedSetDelegate().last();
+ }
+
+ public SortedSet<V> headSet(V toElement) {
+ refreshIfEmpty();
+ return new WrappedSortedSet(
+ getKey(), getSortedSetDelegate().headSet(toElement),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+
+ public SortedSet<V> subSet(V fromElement, V toElement) {
+ refreshIfEmpty();
+ return new WrappedSortedSet(
+ getKey(), getSortedSetDelegate().subSet(fromElement, toElement),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+
+ public SortedSet<V> tailSet(V fromElement) {
+ refreshIfEmpty();
+ return new WrappedSortedSet(
+ getKey(), getSortedSetDelegate().tailSet(fromElement),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+ }
+
+ /** List decorator that stays in sync with the multimap values for a key. */
+ private class WrappedList extends WrappedCollection implements List<V> {
+ WrappedList(K key, List<V> delegate, WrappedCollection ancestor) {
+ super(key, delegate, ancestor);
+ }
+
+ List<V> getListDelegate() {
+ return (List<V>) getDelegate();
+ }
+
+ public boolean addAll(int index, Collection<? extends V> c) {
+ if (c.isEmpty()) {
+ return false;
+ }
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = getListDelegate().addAll(index, c);
+ if (changed) {
+ int newSize = getDelegate().size();
+ totalSize += (newSize - oldSize);
+ if (oldSize == 0) {
+ addToMap();
+ }
+ }
+ return changed;
+ }
+
+ public V get(int index) {
+ refreshIfEmpty();
+ return getListDelegate().get(index);
+ }
+
+ public V set(int index, V element) {
+ refreshIfEmpty();
+ return getListDelegate().set(index, element);
+ }
+
+ public void add(int index, V element) {
+ refreshIfEmpty();
+ boolean wasEmpty = getDelegate().isEmpty();
+ getListDelegate().add(index, element);
+ totalSize++;
+ if (wasEmpty) {
+ addToMap();
+ }
+ }
+
+ public V remove(int index) {
+ refreshIfEmpty();
+ V value = getListDelegate().remove(index);
+ totalSize--;
+ removeIfEmpty();
+ return value;
+ }
+
+ public int indexOf(Object o) {
+ refreshIfEmpty();
+ return getListDelegate().indexOf(o);
+ }
+
+ public int lastIndexOf(Object o) {
+ refreshIfEmpty();
+ return getListDelegate().lastIndexOf(o);
+ }
+
+ public ListIterator<V> listIterator() {
+ refreshIfEmpty();
+ return new WrappedListIterator();
+ }
+
+ public ListIterator<V> listIterator(int index) {
+ refreshIfEmpty();
+ return new WrappedListIterator(index);
+ }
+
+ public List<V> subList(int fromIndex, int toIndex) {
+ refreshIfEmpty();
+ return wrapList(getKey(), getListDelegate().subList(fromIndex, toIndex),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+
+ /** ListIterator decorator. */
+ private class WrappedListIterator extends WrappedIterator
+ implements ListIterator<V> {
+ WrappedListIterator() {}
+
+ public WrappedListIterator(int index) {
+ super(getListDelegate().listIterator(index));
+ }
+
+ private ListIterator<V> getDelegateListIterator() {
+ return (ListIterator<V>) getDelegateIterator();
+ }
+
+ public boolean hasPrevious() {
+ return getDelegateListIterator().hasPrevious();
+ }
+
+ public V previous() {
+ return getDelegateListIterator().previous();
+ }
+
+ public int nextIndex() {
+ return getDelegateListIterator().nextIndex();
+ }
+
+ public int previousIndex() {
+ return getDelegateListIterator().previousIndex();
+ }
+
+ public void set(V value) {
+ getDelegateListIterator().set(value);
+ }
+
+ public void add(V value) {
+ boolean wasEmpty = isEmpty();
+ getDelegateListIterator().add(value);
+ totalSize++;
+ if (wasEmpty) {
+ addToMap();
+ }
+ }
+ }
+ }
+
+ /**
+ * List decorator that stays in sync with the multimap values for a key and
+ * supports rapid random access.
+ */
+ private class RandomAccessWrappedList extends WrappedList
+ implements RandomAccess {
+ RandomAccessWrappedList(K key, List<V> delegate,
+ WrappedCollection ancestor) {
+ super(key, delegate, ancestor);
+ }
+ }
+
+ private transient Set<K> keySet;
+
+ public Set<K> keySet() {
+ Set<K> result = keySet;
+ return (result == null) ? keySet = createKeySet() : result;
+ }
+
+ private Set<K> createKeySet() {
+ return (map instanceof SortedMap)
+ ? new SortedKeySet((SortedMap<K, Collection<V>>) map) : new KeySet(map);
+ }
+
+ private class KeySet extends AbstractSet<K> {
+
+ /**
+ * This is usually the same as map, except when someone requests a
+ * subcollection of a {@link SortedKeySet}.
+ */
+ final Map<K, Collection<V>> subMap;
+
+ KeySet(final Map<K, Collection<V>> subMap) {
+ this.subMap = subMap;
+ }
+
+ @Override public int size() {
+ return subMap.size();
+ }
+
+ @Override public Iterator<K> iterator() {
+ return new Iterator<K>() {
+ final Iterator<Map.Entry<K, Collection<V>>> entryIterator
+ = subMap.entrySet().iterator();
+ Map.Entry<K, Collection<V>> entry;
+
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ public K next() {
+ entry = entryIterator.next();
+ return entry.getKey();
+ }
+ public void remove() {
+ entryIterator.remove();
+ totalSize -= entry.getValue().size();
+ entry.getValue().clear();
+ }
+ };
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+
+ // The following methods are included for better performance.
+
+ @Override public boolean contains(Object key) {
+ return subMap.containsKey(key);
+ }
+
+ @Override public boolean remove(Object key) {
+ int count = 0;
+ Collection<V> collection = subMap.remove(key);
+ if (collection != null) {
+ count = collection.size();
+ collection.clear();
+ totalSize -= count;
+ }
+ return count > 0;
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ return subMap.keySet().containsAll(c);
+ }
+
+ @Override public boolean equals(Object o) {
+ return (o == this) || subMap.keySet().equals(o);
+ }
+
+ @Override public int hashCode() {
+ return subMap.keySet().hashCode();
+ }
+ }
+
+ private class SortedKeySet extends KeySet implements SortedSet<K> {
+
+ SortedKeySet(SortedMap<K, Collection<V>> subMap) {
+ super(subMap);
+ }
+
+ SortedMap<K, Collection<V>> sortedMap() {
+ return (SortedMap<K, Collection<V>>) subMap;
+ }
+
+ public Comparator<? super K> comparator() {
+ return sortedMap().comparator();
+ }
+
+ public K first() {
+ return sortedMap().firstKey();
+ }
+
+ public SortedSet<K> headSet(K toElement) {
+ return new SortedKeySet(sortedMap().headMap(toElement));
+ }
+
+ public K last() {
+ return sortedMap().lastKey();
+ }
+
+ public SortedSet<K> subSet(K fromElement, K toElement) {
+ return new SortedKeySet(sortedMap().subMap(fromElement, toElement));
+ }
+
+ public SortedSet<K> tailSet(K fromElement) {
+ return new SortedKeySet(sortedMap().tailMap(fromElement));
+ }
+ }
+
+ private transient Multiset<K> multiset;
+
+ public Multiset<K> keys() {
+ Multiset<K> result = multiset;
+ return (result == null) ? multiset = new MultisetView() : result;
+ }
+
+ /** Multiset view that stays in sync with the multimap keys. */
+ private class MultisetView extends AbstractMultiset<K> {
+
+ @Override public int remove(Object key, int occurrences) {
+ if (occurrences == 0) {
+ return 0;
+ }
+ checkArgument(occurrences > 0);
+
+ Collection<V> collection;
+ try {
+ collection = map.get(key);
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+
+ if (collection == null) {
+ return 0;
+ }
+ int count = collection.size();
+
+ if (occurrences >= count) {
+ return removeValuesForKey(key);
+ }
+
+ Iterator<V> iterator = collection.iterator();
+ for (int i = 0; i < occurrences; i++) {
+ iterator.next();
+ iterator.remove();
+ }
+ totalSize -= occurrences;
+ return occurrences;
+ }
+
+ @Override public Set<K> elementSet() {
+ return StandardMultimap.this.keySet();
+ }
+
+ transient Set<Multiset.Entry<K>> entrySet;
+
+ @Override public Set<Multiset.Entry<K>> entrySet() {
+ Set<Multiset.Entry<K>> result = entrySet;
+ return (result == null) ? entrySet = new EntrySet() : result;
+ }
+
+ private class EntrySet extends AbstractSet<Multiset.Entry<K>> {
+ @Override public Iterator<Multiset.Entry<K>> iterator() {
+ return new MultisetEntryIterator();
+ }
+ @Override public int size() {
+ return map.size();
+ }
+
+ // The following methods are included for better performance.
+
+ @Override public boolean contains(Object o) {
+ if (!(o instanceof Multiset.Entry)) {
+ return false;
+ }
+ Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
+ Collection<V> collection = map.get(entry.getElement());
+ return (collection != null) &&
+ (collection.size() == entry.getCount());
+ }
+ @Override public void clear() {
+ StandardMultimap.this.clear();
+ }
+ @Override public boolean remove(Object o) {
+ return contains(o) &&
+ (removeValuesForKey(((Multiset.Entry<?>) o).getElement()) > 0);
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+ }
+
+ @Override public Iterator<K> iterator() {
+ return new MultisetKeyIterator();
+ }
+
+ // The following methods are included for better performance.
+
+ @Override public int count(Object key) {
+ try {
+ Collection<V> collection = map.get(key);
+ return (collection == null) ? 0 : collection.size();
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+ }
+
+ @Override public int removeAllOccurrences(Object key) {
+ return removeValuesForKey(key);
+ }
+
+ @Override public int size() {
+ return totalSize;
+ }
+
+ @Override public void clear() {
+ StandardMultimap.this.clear();
+ }
+ }
+
+ /**
+ * Removes all values for the provided key. Unlike {@link #removeAll}, it
+ * returns the number of removed mappings.
+ */
+ private int removeValuesForKey(Object key) {
+ Collection<V> collection;
+ try {
+ collection = map.remove(key);
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+
+ int count = 0;
+ if (collection != null) {
+ count = collection.size();
+ collection.clear();
+ totalSize -= count;
+ }
+ return count;
+ }
+
+ /** Iterator across each key, repeating once per value. */
+ private class MultisetEntryIterator implements Iterator<Multiset.Entry<K>> {
+ final Iterator<Map.Entry<K, Collection<V>>> asMapIterator
+ = asMap().entrySet().iterator();
+
+ public boolean hasNext() {
+ return asMapIterator.hasNext();
+ }
+ public Multiset.Entry<K> next() {
+ return new MultisetEntry(asMapIterator.next());
+ }
+ public void remove() {
+ asMapIterator.remove();
+ }
+ }
+
+ private class MultisetEntry extends AbstractMultisetEntry<K> {
+ final Map.Entry<K, Collection<V>> entry;
+
+ public MultisetEntry(Map.Entry<K, Collection<V>> entry) {
+ this.entry = entry;
+ }
+ public K getElement() {
+ return entry.getKey();
+ }
+ public int getCount() {
+ return entry.getValue().size();
+ }
+ }
+
+ /** Iterator across each key, repeating once per value. */
+ private class MultisetKeyIterator implements Iterator<K> {
+ final Iterator<Map.Entry<K, V>> entryIterator = entries().iterator();
+
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ public K next() {
+ return entryIterator.next().getKey();
+ }
+ public void remove() {
+ entryIterator.remove();
+ }
+ }
+
+ private transient Collection<V> valuesCollection;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The iterator generated by the returned collection traverses the values
+ * for one key, followed by the values of a second key, and so on.
+ */
+ public Collection<V> values() {
+ Collection<V> result = valuesCollection;
+ return (result == null) ? valuesCollection = new Values() : result;
+ }
+
+ private class Values extends AbstractCollection<V> {
+ @Override public Iterator<V> iterator() {
+ return new ValueIterator();
+ }
+ @Override public int size() {
+ return totalSize;
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return super.removeAll(checkNotNull(c));
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+
+ // The following methods are included to improve performance.
+
+ @Override public void clear() {
+ StandardMultimap.this.clear();
+ }
+
+ @Override public boolean contains(Object value) {
+ return containsValue(value);
+ }
+ }
+
+ /** Iterator across all values. */
+ private class ValueIterator implements Iterator<V> {
+ final Iterator<Map.Entry<K, V>> entryIterator = createEntryIterator();
+
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ public V next() {
+ return entryIterator.next().getValue();
+ }
+ public void remove() {
+ entryIterator.remove();
+ }
+ }
+
+ private transient Collection<Map.Entry<K, V>> entries;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The iterator generated by the returned collection traverses the values
+ * for one key, followed by the values of a second key, and so on.
+ */
+ public Collection<Map.Entry<K, V>> entries() {
+ Collection<Map.Entry<K, V>> result = entries;
+ return (entries == null) ? entries = createEntries() : result;
+ }
+
+ private Collection<Map.Entry<K, V>> createEntries() {
+ // TODO: can we refactor so we're not doing "this instanceof"?
+ return (this instanceof SetMultimap) ? new EntrySet() : new Entries();
+ }
+
+ /** Entries for multimap. */
+ private class Entries extends AbstractCollection<Map.Entry<K, V>> {
+ @Override public Iterator<Map.Entry<K, V>> iterator() {
+ return createEntryIterator();
+ }
+ @Override public int size() {
+ return totalSize;
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ return super.removeAll(checkNotNull(c));
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ return super.retainAll(checkNotNull(c));
+ }
+
+ // The following methods are included to improve performance.
+
+ @Override public boolean contains(Object o) {
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+ return containsEntry(entry.getKey(), entry.getValue());
+ }
+
+ @Override public void clear() {
+ StandardMultimap.this.clear();
+ }
+
+ @Override public boolean remove(Object o) {
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+ return StandardMultimap.this.remove(entry.getKey(), entry.getValue());
+ }
+ }
+
+ /**
+ * Returns an iterator across all key-value map entries, used by {@code
+ * entries().iterator()} and {@code values().iterator()}. The default
+ * behavior, which traverses the values for one key, the values for a second
+ * key, and so on, suffices for most {@code StandardMultimap} implementations.
+ *
+ * @return an iterator across map entries
+ */
+ Iterator<Map.Entry<K, V>> createEntryIterator() {
+ return new EntryIterator();
+ }
+
+ /** Iterator across all key-value pairs. */
+ private class EntryIterator implements Iterator<Map.Entry<K, V>> {
+ final Iterator<Map.Entry<K, Collection<V>>> keyIterator;
+ K key;
+ Collection<V> collection;
+ Iterator<V> valueIterator;
+
+ EntryIterator() {
+ keyIterator = map.entrySet().iterator();
+ if (keyIterator.hasNext()) {
+ findValueIteratorAndKey();
+ } else {
+ valueIterator = Iterators.emptyModifiableIterator();
+ }
+ }
+
+ void findValueIteratorAndKey() {
+ Map.Entry<K, Collection<V>> entry = keyIterator.next();
+ key = entry.getKey();
+ collection = entry.getValue();
+ valueIterator = iteratorOrListIterator(collection);
+ }
+
+ public boolean hasNext() {
+ return keyIterator.hasNext() || valueIterator.hasNext();
+ }
+
+ public Map.Entry<K, V> next() {
+ if (!valueIterator.hasNext()) {
+ findValueIteratorAndKey();
+ }
+ return (valueIterator instanceof ListIterator)
+ ? new ListMapEntry(key, (ListIterator<V>) valueIterator)
+ : Maps.immutableEntry(key, valueIterator.next());
+ }
+
+ public void remove() {
+ valueIterator.remove();
+ if (collection.isEmpty()) {
+ keyIterator.remove();
+ }
+ totalSize--;
+ }
+ }
+
+ /**
+ * Map entry that allows value modification through provided list iterator.
+ */
+ private class ListMapEntry extends AbstractMapEntry<K, V> {
+ final K key;
+ V value;
+ final ListIterator<V> iterator;
+
+ ListMapEntry(K key, ListIterator<V> iterator) {
+ this.key = key;
+ this.value = iterator.next();
+ this.iterator = iterator;
+ }
+ @Override public K getKey() {
+ return key;
+ }
+ @Override public V getValue() {
+ return value;
+ }
+ @Override public V setValue(V newValue) {
+ V oldValue = value;
+ iterator.set(newValue);
+ value = newValue;
+ return oldValue;
+ }
+ }
+
+ /** Entry set for a {@link SetMultimap}. */
+ private class EntrySet extends Entries implements Set<Map.Entry<K, V>> {
+ @Override public boolean equals(Object other) {
+ return Sets.equalsImpl(this, other);
+ }
+ @Override public int hashCode() {
+ return Sets.hashCodeImpl(this);
+ }
+ }
+
+ private transient Map<K, Collection<V>> asMap;
+
+ public Map<K, Collection<V>> asMap() {
+ Map<K, Collection<V>> result = asMap;
+ return (result == null) ? asMap = new AsMap() : result;
+ }
+
+ private class AsMap extends AbstractMap<K, Collection<V>> {
+ transient Set<Map.Entry<K, Collection<V>>> entrySet;
+
+ @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
+ Set<Map.Entry<K, Collection<V>>> result = entrySet;
+ return (entrySet == null) ? entrySet = new AsMapEntries() : result;
+ }
+
+ // The following methods are included for performance.
+
+ @Override public void clear() {
+ StandardMultimap.this.clear();
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return map.containsKey(key);
+ }
+
+ @Override public Collection<V> get(Object key) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ return null;
+ }
+ @SuppressWarnings("unchecked")
+ K k = (K) key;
+ return wrapCollection(k, collection);
+ }
+
+ @Override public Set<K> keySet() {
+ return StandardMultimap.this.keySet();
+ }
+
+ @Override public Collection<V> remove(Object key) {
+ Collection<V> collection = removeAll(key);
+ return collection.isEmpty() ? null : collection;
+ }
+
+ @Override public boolean equals(Object other) {
+ return (this == other) || map.equals(other);
+ }
+
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ return map.toString();
+ }
+ }
+
+ private class AsMapEntries extends AbstractSet<Map.Entry<K, Collection<V>>> {
+ @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
+ return new AsMapIterator();
+ }
+
+ @Override public int size() {
+ return map.size();
+ }
+
+ // The following methods are included for performance.
+
+ @Override public void clear() {
+ StandardMultimap.this.clear();
+ }
+
+ @Override public boolean contains(Object o) {
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+ return (entry.getValue() != null)
+ && Objects.equal(map.get(entry.getKey()), entry.getValue());
+ }
+
+ @Override public boolean remove(Object o) {
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+ return contains(entry) && (removeValuesForKey(entry.getKey()) > 0);
+ }
+ }
+
+ /** Iterator across all keys and value collections. */
+ private class AsMapIterator implements Iterator<Map.Entry<K, Collection<V>>> {
+ final Iterator<Map.Entry<K, Collection<V>>> delegateIterator
+ = map.entrySet().iterator();
+ Collection<V> collection;
+
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+ public Map.Entry<K, Collection<V>> next() {
+ Map.Entry<K, Collection<V>> entry = delegateIterator.next();
+ K key = entry.getKey();
+ collection = entry.getValue();
+ return Maps.immutableEntry(key, wrapCollection(key, collection));
+ }
+ public void remove() {
+ delegateIterator.remove();
+ totalSize -= collection.size();
+ collection.clear();
+ }
+ }
+
+ // Comparison and hashing
+
+ @Override public boolean equals(@Nullable Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof Multimap)) {
+ return false;
+ }
+ Multimap<?, ?> otherMultimap = (Multimap<?, ?>) other;
+ return map.equals(otherMultimap.asMap());
+ }
+
+ /**
+ * Returns the hash code for this multimap.
+ *
+ * <p>The hash code of a multimap is defined as the hash code of the map view,
+ * as returned by {@link Multimap#asMap}.
+ *
+ * @see Map#hashCode
+ */
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ /**
+ * Returns a string representation of the multimap, generated by calling
+ * {@code toString} on the map returned by {@link Multimap#asMap}.
+ *
+ * @return a string representation of the multimap
+ */
+ @Override public String toString() {
+ return map.toString();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSetMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSetMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSetMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Basic implementation of the {@link SetMultimap} interface. It's a wrapper
+ * around {@link StandardMultimap} that converts the returned collections into
+ * {@code Sets}. The {@link #createCollection} method must return a {@code Set}.
+ *
+ * @author Jared Levy
+ */
+abstract class StandardSetMultimap<K, V>
+ extends StandardMultimap<K, V> implements SetMultimap<K, V> {
+ /**
+ * Creates a new multimap that uses the provided map.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ */
+ protected StandardSetMultimap(Map<K, Collection<V>> map) {
+ super(map);
+ }
+
+ @Override abstract Set<V> createCollection();
+
+ @Override public Set<V> get(@Nullable K key) {
+ return (Set<V>) super.get(key);
+ }
+
+ @Override public Set<Map.Entry<K, V>> entries() {
+ return (Set<Map.Entry<K, V>>) super.entries();
+ }
+
+ @Override public Set<V> removeAll(@Nullable Object key) {
+ return (Set<V>) super.removeAll(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Any duplicates in {@code values} will be stored in the multimap once.
+ */
+ @Override public Set<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
+ return (Set<V>) super.replaceValues(key, values);
+ }
+
+ /**
+ * Stores a key-value pair in the multimap.
+ *
+ * @param key key to store in the multimap
+ * @param value value to store in the multimap
+ * @return {@code true} if the method increased the size of the multimap, or
+ * {@code false} if the multimap already contained the key-value pair
+ */
+ @Override public boolean put(K key, V value) {
+ return super.put(key, value);
+ }
+
+ /**
+ * Compares the specified object to this multimap for equality.
+ *
+ * <p>Two {@code SetMultimap} instances are equal if, for each key, they
+ * contain the same values. Equality does not depend on the ordering of keys
+ * or values.
+ */
+ @Override public boolean equals(@Nullable Object obj) {
+ return super.equals(obj);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSortedSetMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSortedSetMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/StandardSortedSetMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.SortedSet;
+
+/**
+ * Basic implementation of the {@link SortedSetMultimap} interface. It's a
+ * wrapper around {@link StandardMultimap} that converts the returned
+ * collections into sorted sets. The {@link #createCollection} method
+ * must return a {@code SortedSet}.
+ *
+ * @author Jared Levy
+ */
+abstract class StandardSortedSetMultimap<K, V>
+ extends StandardSetMultimap<K, V> implements SortedSetMultimap<K, V> {
+ /**
+ * Creates a new multimap that uses the provided map.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ */
+ protected StandardSortedSetMultimap(Map<K, Collection<V>> map) {
+ super(map);
+ }
+
+ @Override abstract SortedSet<V> createCollection();
+
+ @Override public SortedSet<V> get(@Nullable K key) {
+ return (SortedSet<V>) super.get(key);
+ }
+
+ @Override public SortedSet<V> removeAll(@Nullable Object key) {
+ return (SortedSet<V>) super.removeAll(key);
+ }
+
+ @Override public SortedSet<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ return (SortedSet<V>) super.replaceValues(key, values);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Consequently, the values do not follow their natural ordering or the
+ * ordering of the value comparator.
+ */
+ @Override public Collection<V> values() {
+ return super.values();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Synchronized.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Synchronized.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/Synchronized.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,1366 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import static org.richfaces.collections.base.Preconditions.checkNotNull;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.RandomAccess;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * Synchronized collection views. The returned synchronized collection views are
+ * serializable if the backing collection and the mutex are serializable.
+ *
+ * <p>If a {@code null} is passed as the {@code mutex} parameter to any of this
+ * class's top-level methods or inner class constructors, the created object
+ * uses itself as the synchronization mutex.
+ *
+ * @author Mike Bostock
+ * @author Jared Levy
+ */
+final class Synchronized {
+ private Synchronized() {}
+
+ /** Abstract base class for synchronized views. */
+ static class SynchronizedObject implements Serializable {
+ private final Object delegate;
+ protected final Object mutex;
+
+ public SynchronizedObject(Object delegate, Object mutex) {
+ this.delegate = checkNotNull(delegate);
+ this.mutex = (mutex == null) ? this : mutex;
+ }
+
+ protected Object delegate() {
+ return delegate;
+ }
+
+ // No equals and hashCode; see ForwardingObject for details.
+
+ @Override public String toString() {
+ synchronized (mutex) {
+ return delegate.toString();
+ }
+ }
+
+ protected void writeObject(ObjectOutputStream stream) throws IOException {
+ synchronized (mutex) {
+ stream.defaultWriteObject();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) collection backed by the specified
+ * collection using the specified mutex. In order to guarantee serial access,
+ * it is critical that <b>all</b> access to the backing collection is
+ * accomplished through the returned collection.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned collection:
+ *
+ * <pre>Collection<E> s = Synchronized.collection(
+ * new HashSet<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param collection the collection to be wrapped in a synchronized view
+ * @return a synchronized view of the specified collection
+ */
+ static <E> Collection<E> collection(Collection<E> collection, Object mutex) {
+ return new SynchronizedCollection<E>(collection, mutex);
+ }
+
+ /** @see Synchronized#collection */
+ static class SynchronizedCollection<E> extends SynchronizedObject
+ implements Collection<E> {
+ public SynchronizedCollection(Collection<E> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override protected Collection<E> delegate() {
+ return (Collection<E>) super.delegate();
+ }
+
+ public boolean add(E e) {
+ synchronized (mutex) {
+ return delegate().add(e);
+ }
+ }
+
+ public boolean addAll(Collection<? extends E> c) {
+ synchronized (mutex) {
+ return delegate().addAll(c);
+ }
+ }
+
+ public void clear() {
+ synchronized (mutex) {
+ delegate().clear();
+ }
+ }
+
+ public boolean contains(Object o) {
+ synchronized (mutex) {
+ return delegate().contains(o);
+ }
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ synchronized (mutex) {
+ return delegate().containsAll(c);
+ }
+ }
+
+ public boolean isEmpty() {
+ synchronized (mutex) {
+ return delegate().isEmpty();
+ }
+ }
+
+ public Iterator<E> iterator() {
+ return delegate().iterator(); // manually synchronized
+ }
+
+ public boolean remove(Object o) {
+ synchronized (mutex) {
+ return delegate().remove(o);
+ }
+ }
+
+ public boolean removeAll(Collection<?> c) {
+ synchronized (mutex) {
+ return delegate().removeAll(c);
+ }
+ }
+
+ public boolean retainAll(Collection<?> c) {
+ synchronized (mutex) {
+ return delegate().retainAll(c);
+ }
+ }
+
+ public int size() {
+ synchronized (mutex) {
+ return delegate().size();
+ }
+ }
+
+ public Object[] toArray() {
+ synchronized (mutex) {
+ return delegate().toArray();
+ }
+ }
+
+ public <T> T[] toArray(T[] a) {
+ synchronized (mutex) {
+ return delegate().toArray(a);
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) set backed by the specified set using
+ * the specified mutex. In order to guarantee serial access, it is critical
+ * that <b>all</b> access to the backing set is accomplished through the
+ * returned set.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned set:
+ *
+ * <pre>Set<E> s = Synchronized.set(new HashSet<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param set the set to be wrapped in a synchronized view
+ * @return a synchronized view of the specified set
+ */
+ public static <E> Set<E> set(Set<E> set, Object mutex) {
+ return new SynchronizedSet<E>(set, mutex);
+ }
+
+ /** @see Synchronized#set */
+ static class SynchronizedSet<E> extends SynchronizedCollection<E>
+ implements Set<E> {
+ public SynchronizedSet(Set<E> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override protected Set<E> delegate() {
+ return (Set<E>) super.delegate();
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ synchronized (mutex) {
+ return delegate().equals(o);
+ }
+ }
+
+ @Override public int hashCode() {
+ synchronized (mutex) {
+ return delegate().hashCode();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) sorted set backed by the specified
+ * sorted set using the specified mutex. In order to guarantee serial access,
+ * it is critical that <b>all</b> access to the backing sorted set is
+ * accomplished through the returned sorted set.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned sorted set:
+ *
+ * <pre>SortedSet<E> s = Synchronized.sortedSet(
+ * new TreeSet<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param set the sorted set to be wrapped in a synchronized view
+ * @return a synchronized view of the specified sorted set
+ */
+ static <E> SortedSet<E> sortedSet(SortedSet<E> set, Object mutex) {
+ return new SynchronizedSortedSet<E>(set, mutex);
+ }
+
+ /** @see Synchronized#sortedSet */
+ static class SynchronizedSortedSet<E> extends SynchronizedSet<E>
+ implements SortedSet<E> {
+ public SynchronizedSortedSet(SortedSet<E> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override protected SortedSet<E> delegate() {
+ return (SortedSet<E>) super.delegate();
+ }
+
+ public Comparator<? super E> comparator() {
+ synchronized (mutex) {
+ return delegate().comparator();
+ }
+ }
+
+ public SortedSet<E> subSet(E fromElement, E toElement) {
+ synchronized (mutex) {
+ return sortedSet(delegate().subSet(fromElement, toElement), mutex);
+ }
+ }
+
+ public SortedSet<E> headSet(E toElement) {
+ synchronized (mutex) {
+ return sortedSet(delegate().headSet(toElement), mutex);
+ }
+ }
+
+ public SortedSet<E> tailSet(E fromElement) {
+ synchronized (mutex) {
+ return sortedSet(delegate().tailSet(fromElement), mutex);
+ }
+ }
+
+ public E first() {
+ synchronized (mutex) {
+ return delegate().first();
+ }
+ }
+
+ public E last() {
+ synchronized (mutex) {
+ return delegate().last();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) list backed by the specified list
+ * using the specified mutex. In order to guarantee serial access, it is
+ * critical that <b>all</b> access to the backing list is accomplished
+ * through the returned list.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned list:
+ *
+ * <pre>List<E> l = Synchronized.list(new ArrayList<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = l.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>The returned list implements {@link RandomAccess} if the specified list
+ * implements {@code RandomAccess}.
+ *
+ * @param list the list to be wrapped in a synchronized view
+ * @return a synchronized view of the specified list
+ */
+ static <E> List<E> list(List<E> list, Object mutex) {
+ return (list instanceof RandomAccess)
+ ? new SynchronizedRandomAccessList<E>(list, mutex)
+ : new SynchronizedList<E>(list, mutex);
+ }
+
+ /** @see Synchronized#list */
+ static class SynchronizedList<E> extends SynchronizedCollection<E>
+ implements List<E> {
+ public SynchronizedList(List<E> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override protected List<E> delegate() {
+ return (List<E>) super.delegate();
+ }
+
+ public void add(int index, E element) {
+ synchronized (mutex) {
+ delegate().add(index, element);
+ }
+ }
+
+ public boolean addAll(int index, Collection<? extends E> c) {
+ synchronized (mutex) {
+ return delegate().addAll(index, c);
+ }
+ }
+
+ public E get(int index) {
+ synchronized (mutex) {
+ return delegate().get(index);
+ }
+ }
+
+ public int indexOf(Object o) {
+ synchronized (mutex) {
+ return delegate().indexOf(o);
+ }
+ }
+
+ public int lastIndexOf(Object o) {
+ synchronized (mutex) {
+ return delegate().lastIndexOf(o);
+ }
+ }
+
+ public ListIterator<E> listIterator() {
+ return delegate().listIterator(); // manually synchronized
+ }
+
+ public ListIterator<E> listIterator(int index) {
+ return delegate().listIterator(index); // manually synchronized
+ }
+
+ public E remove(int index) {
+ synchronized (mutex) {
+ return delegate().remove(index);
+ }
+ }
+
+ public E set(int index, E element) {
+ synchronized (mutex) {
+ return delegate().set(index, element);
+ }
+ }
+
+ public List<E> subList(int fromIndex, int toIndex) {
+ synchronized (mutex) {
+ return list(delegate().subList(fromIndex, toIndex), mutex);
+ }
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ synchronized (mutex) {
+ return delegate().equals(o);
+ }
+ }
+
+ @Override public int hashCode() {
+ synchronized (mutex) {
+ return delegate().hashCode();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see Synchronized#list */
+ static class SynchronizedRandomAccessList<E> extends SynchronizedList<E>
+ implements RandomAccess {
+ public SynchronizedRandomAccessList(List<E> list, Object mutex) {
+ super(list, mutex);
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) multiset backed by the specified
+ * multiset using the specified mutex. In order to guarantee serial access, it
+ * is critical that <b>all</b> access to the backing multiset is accomplished
+ * through the returned multiset.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned multiset:
+ *
+ * <pre>Multiset<E> s = Synchronized.multiset(
+ * new HashMultiset<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param multiset the multiset to be wrapped
+ * @return a synchronized view of the specified multiset
+ */
+ public static <E> Multiset<E> multiset(Multiset<E> multiset, Object mutex) {
+ return new SynchronizedMultiset<E>(multiset, mutex);
+ }
+
+ /** @see Synchronized#multiset */
+ static class SynchronizedMultiset<E> extends SynchronizedCollection<E>
+ implements Multiset<E> {
+ private transient Set<E> elementSet;
+ private transient Set<Entry<E>> entrySet;
+
+ public SynchronizedMultiset(Multiset<E> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override protected Multiset<E> delegate() {
+ return (Multiset<E>) super.delegate();
+ }
+
+ public int count(Object o) {
+ synchronized (mutex) {
+ return delegate().count(o);
+ }
+ }
+
+ public boolean add(E e, int n) {
+ synchronized (mutex) {
+ return delegate().add(e, n);
+ }
+ }
+
+ public int remove(Object o, int n) {
+ synchronized (mutex) {
+ return delegate().remove(o, n);
+ }
+ }
+
+ public int removeAllOccurrences(Object o) {
+ synchronized (mutex) {
+ return delegate().removeAllOccurrences(o);
+ }
+ }
+
+ public Set<E> elementSet() {
+ synchronized (mutex) {
+ if (elementSet == null) {
+ elementSet = typePreservingSet(delegate().elementSet(), mutex);
+ }
+ return elementSet;
+ }
+ }
+
+ public Set<Entry<E>> entrySet() {
+ synchronized (mutex) {
+ if (entrySet == null) {
+ entrySet = typePreservingSet(delegate().entrySet(), mutex);
+ }
+ return entrySet;
+ }
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ synchronized (mutex) {
+ return delegate().equals(o);
+ }
+ }
+
+ @Override public int hashCode() {
+ synchronized (mutex) {
+ return delegate().hashCode();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) multimap backed by the specified
+ * multimap using the specified mutex. In order to guarantee serial access, it
+ * is critical that <b>all</b> access to the backing multimap is accomplished
+ * through the returned multimap.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when accessing any of the return multimap's collection views:
+ *
+ * <pre>Multimap<K,V> m = Synchronized.multimap(
+ * new HashMultimap<K,V>(), mutex);
+ * ...
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (mutex) {
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param multimap the multimap to be wrapped in a synchronized view
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> Multimap<K, V> multimap(
+ Multimap<K, V> multimap, Object mutex) {
+ return new SynchronizedMultimap<K, V>(multimap, mutex);
+ }
+
+ /** @see Synchronized#multimap */
+ private static class SynchronizedMultimap<K, V> extends SynchronizedObject
+ implements Multimap<K, V> {
+ transient Set<K> keySet;
+ transient Collection<V> valuesCollection;
+ transient Collection<Map.Entry<K, V>> entries;
+ transient Map<K, Collection<V>> asMap;
+ transient Multiset<K> keys;
+
+ @SuppressWarnings("unchecked")
+ @Override protected Multimap<K, V> delegate() {
+ return (Multimap<K, V>) super.delegate();
+ }
+
+ SynchronizedMultimap(Multimap<K, V> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ public int size() {
+ synchronized (mutex) {
+ return delegate().size();
+ }
+ }
+
+ public boolean isEmpty() {
+ synchronized (mutex) {
+ return delegate().isEmpty();
+ }
+ }
+
+ public boolean containsKey(Object key) {
+ synchronized (mutex) {
+ return delegate().containsKey(key);
+ }
+ }
+
+ public boolean containsValue(Object value) {
+ synchronized (mutex) {
+ return delegate().containsValue(value);
+ }
+ }
+
+ public boolean containsEntry(Object key, Object value) {
+ synchronized (mutex) {
+ return delegate().containsEntry(key, value);
+ }
+ }
+
+ public Collection<V> get(K key) {
+ synchronized (mutex) {
+ return typePreservingCollection(delegate().get(key), mutex);
+ }
+ }
+
+ public boolean put(K key, V value) {
+ synchronized (mutex) {
+ return delegate().put(key, value);
+ }
+ }
+
+ public boolean putAll(K key, Iterable<? extends V> values) {
+ synchronized (mutex) {
+ return delegate().putAll(key, values);
+ }
+ }
+
+ public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ synchronized (mutex) {
+ return delegate().putAll(multimap);
+ }
+ }
+
+ public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
+ synchronized (mutex) {
+ return delegate().replaceValues(key, values); // copy not synchronized
+ }
+ }
+
+ public boolean remove(Object key, Object value) {
+ synchronized (mutex) {
+ return delegate().remove(key, value);
+ }
+ }
+
+ public Collection<V> removeAll(Object key) {
+ synchronized (mutex) {
+ return delegate().removeAll(key); // copy not synchronized
+ }
+ }
+
+ public void clear() {
+ synchronized (mutex) {
+ delegate().clear();
+ }
+ }
+
+ public Set<K> keySet() {
+ synchronized (mutex) {
+ if (keySet == null) {
+ keySet = typePreservingSet(delegate().keySet(), mutex);
+ }
+ return keySet;
+ }
+ }
+
+ public Collection<V> values() {
+ synchronized (mutex) {
+ if (valuesCollection == null) {
+ valuesCollection = collection(delegate().values(), mutex);
+ }
+ return valuesCollection;
+ }
+ }
+
+ public Collection<Map.Entry<K, V>> entries() {
+ synchronized (mutex) {
+ if (entries == null) {
+ entries = typePreservingCollection(delegate().entries(), mutex);
+ }
+ return entries;
+ }
+ }
+
+ public Map<K, Collection<V>> asMap() {
+ synchronized (mutex) {
+ if (asMap == null) {
+ asMap = new SynchronizedAsMap<K, V>(delegate().asMap(), mutex);
+ }
+ return asMap;
+ }
+ }
+
+ public Multiset<K> keys() {
+ synchronized (mutex) {
+ if (keys == null) {
+ keys = multiset(delegate().keys(), mutex);
+ }
+ return keys;
+ }
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ synchronized (mutex) {
+ return delegate().equals(o);
+ }
+ }
+
+ @Override public int hashCode() {
+ synchronized (mutex) {
+ return delegate().hashCode();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) list multimap backed by the specified
+ * multimap using the specified mutex.
+ *
+ * <p>You must follow the warnings described for {@link #multimap}.
+ *
+ * @param multimap the multimap to be wrapped in a synchronized view
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> ListMultimap<K, V> listMultimap(
+ ListMultimap<K, V> multimap, Object mutex) {
+ return new SynchronizedListMultimap<K, V>(multimap, mutex);
+ }
+
+ /** @see Synchronized#listMultimap */
+ private static class SynchronizedListMultimap<K, V>
+ extends SynchronizedMultimap<K, V> implements ListMultimap<K, V> {
+ SynchronizedListMultimap(ListMultimap<K, V> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+ @Override protected ListMultimap<K, V> delegate() {
+ return (ListMultimap<K, V>) super.delegate();
+ }
+ @Override public List<V> get(K key) {
+ synchronized (mutex) {
+ return list(delegate().get(key), mutex);
+ }
+ }
+ @Override public List<V> removeAll(Object key) {
+ synchronized (mutex) {
+ return delegate().removeAll(key); // copy not synchronized
+ }
+ }
+ @Override public List<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ synchronized (mutex) {
+ return delegate().replaceValues(key, values); // copy not synchronized
+ }
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) set multimap backed by the specified
+ * multimap using the specified mutex.
+ *
+ * <p>You must follow the warnings described for {@link #multimap}.
+ *
+ * @param multimap the multimap to be wrapped in a synchronized view
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> SetMultimap<K, V> setMultimap(
+ SetMultimap<K, V> multimap, Object mutex) {
+ return new SynchronizedSetMultimap<K, V>(multimap, mutex);
+ }
+
+ /** @see Synchronized#setMultimap */
+ private static class SynchronizedSetMultimap<K, V>
+ extends SynchronizedMultimap<K, V> implements SetMultimap<K, V> {
+ transient Set<Map.Entry<K, V>> entrySet;
+ SynchronizedSetMultimap(SetMultimap<K, V> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+ @Override protected SetMultimap<K, V> delegate() {
+ return (SetMultimap<K, V>) super.delegate();
+ }
+ @Override public Set<V> get(K key) {
+ synchronized (mutex) {
+ return set(delegate().get(key), mutex);
+ }
+ }
+ @Override public Set<V> removeAll(Object key) {
+ synchronized (mutex) {
+ return delegate().removeAll(key); // copy not synchronized
+ }
+ }
+ @Override public Set<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ synchronized (mutex) {
+ return delegate().replaceValues(key, values); // copy not synchronized
+ }
+ }
+ @Override public Set<Map.Entry<K, V>> entries() {
+ synchronized (mutex) {
+ if (entrySet == null) {
+ entrySet = set(delegate().entries(), mutex);
+ }
+ return entrySet;
+ }
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) sorted set multimap backed by the
+ * specified multimap using the specified mutex.
+ *
+ * <p>You must follow the warnings described for {@link #multimap}.
+ *
+ * @param multimap the multimap to be wrapped in a synchronized view
+ * @return a synchronized view of the specified multimap
+ */
+ public static <K, V> SortedSetMultimap<K, V> sortedSetMultimap(
+ SortedSetMultimap<K, V> multimap, Object mutex) {
+ return new SynchronizedSortedSetMultimap<K, V>(multimap, mutex);
+ }
+
+ /** @see Synchronized#sortedSetMultimap */
+ private static class SynchronizedSortedSetMultimap<K, V>
+ extends SynchronizedSetMultimap<K, V> implements SortedSetMultimap<K, V> {
+ SynchronizedSortedSetMultimap(
+ SortedSetMultimap<K, V> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+ @Override protected SortedSetMultimap<K, V> delegate() {
+ return (SortedSetMultimap<K, V>) super.delegate();
+ }
+ @Override public SortedSet<V> get(K key) {
+ synchronized (mutex) {
+ return sortedSet(delegate().get(key), mutex);
+ }
+ }
+ @Override public SortedSet<V> removeAll(Object key) {
+ synchronized (mutex) {
+ return delegate().removeAll(key); // copy not synchronized
+ }
+ }
+ @Override public SortedSet<V> replaceValues(
+ K key, Iterable<? extends V> values) {
+ synchronized (mutex) {
+ return delegate().replaceValues(key, values); // copy not synchronized
+ }
+ }
+ public Comparator<? super V> valueComparator() {
+ synchronized (mutex) {
+ return delegate().valueComparator();
+ }
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) collection backed by the specified
+ * collection using the specified mutex. In order to guarantee serial access,
+ * it is critical that <b>all</b> access to the backing collection is
+ * accomplished through the returned collection.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned collection:
+ *
+ * <pre>Collection<E> s = Synchronized.typePreservingCollection(
+ * new HashSet<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>If the specified collection is a {@code SortedSet}, {@code Set} or
+ * {@code List}, this method will behave identically to {@link #sortedSet},
+ * {@link #set} or {@link #list} respectively, in that order of specificity.
+ *
+ * @param collection the collection to be wrapped in a synchronized view
+ * @return a synchronized view of the specified collection
+ */
+ private static <E> Collection<E> typePreservingCollection(
+ Collection<E> collection, Object mutex) {
+ if (collection instanceof SortedSet) {
+ return sortedSet((SortedSet<E>) collection, mutex);
+ } else if (collection instanceof Set) {
+ return set((Set<E>) collection, mutex);
+ } else if (collection instanceof List) {
+ return list((List<E>) collection, mutex);
+ } else {
+ return collection(collection, mutex);
+ }
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) set backed by the specified set using
+ * the specified mutex. In order to guarantee serial access, it is critical
+ * that <b>all</b> access to the backing collection is accomplished through
+ * the returned collection.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when iterating over the returned collection:
+ *
+ * <pre>Set<E> s = Synchronized.typePreservingSet(
+ * new HashSet<E>(), mutex);
+ * ...
+ * synchronized (mutex) {
+ * Iterator<E> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>If the specified collection is a {@code SortedSet} this method will
+ * behave identically to {@link #sortedSet}.
+ *
+ * @param set the set to be wrapped in a synchronized view
+ * @return a synchronized view of the specified set
+ */
+ public static <E> Set<E> typePreservingSet(Set<E> set, Object mutex) {
+ if (set instanceof SortedSet) {
+ return sortedSet((SortedSet<E>) set, mutex);
+ } else {
+ return set(set, mutex);
+ }
+ }
+
+ /** @see Synchronized#multimap */
+ static class SynchronizedAsMapEntries<K, V>
+ extends SynchronizedSet<Map.Entry<K, Collection<V>>> {
+ public SynchronizedAsMapEntries(
+ Set<Map.Entry<K, Collection<V>>> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
+ final Iterator<Map.Entry<K, Collection<V>>> iterator = super.iterator();
+ // The iterator and entry aren't synchronized, but the entry value is.
+ return new ForwardingIterator<Map.Entry<K, Collection<V>>>() {
+ @Override protected Iterator<Map.Entry<K, Collection<V>>> delegate() {
+ return iterator;
+ }
+
+ @Override public Map.Entry<K, Collection<V>> next() {
+ final Map.Entry<K, Collection<V>> entry = iterator.next();
+ return new ForwardingMapEntry<K, Collection<V>>() {
+ @Override protected Map.Entry<K, Collection<V>> delegate() {
+ return entry;
+ }
+ @Override public Collection<V> getValue() {
+ return typePreservingCollection(entry.getValue(), mutex);
+ }
+ };
+ }
+ };
+ }
+
+ // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
+
+ @Override public Object[] toArray() {
+ synchronized (mutex) {
+ return ObjectArrays.toArrayImpl(delegate());
+ }
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ synchronized (mutex) {
+ return ObjectArrays.toArrayImpl(delegate(), array);
+ }
+ }
+ @Override public boolean contains(Object o) {
+ synchronized (mutex) {
+ return Maps.containsEntryImpl(delegate(), o);
+ }
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ synchronized (mutex) {
+ return Collections2.containsAll(delegate(), c);
+ }
+ }
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ synchronized (mutex) {
+ return Sets.equalsImpl(delegate(), o);
+ }
+ }
+ @Override public boolean remove(Object o) {
+ synchronized (mutex) {
+ return Maps.removeEntryImpl(delegate(), o);
+ }
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ synchronized (mutex) {
+ return Iterators.removeAll(delegate().iterator(), c);
+ }
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ synchronized (mutex) {
+ return Iterators.retainAll(delegate().iterator(), c);
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) map backed by the specified map using
+ * the specified mutex. In order to guarantee serial access, it is critical
+ * that <b>all</b> access to the backing map is accomplished through the
+ * returned map.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when accessing any of the return map's collection views:
+ *
+ * <pre>Map<K,V> m = Synchronized.map(
+ * new HashMap<K,V>(), mutex);
+ * ...
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (mutex) {
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param map the map to be wrapped in a synchronized view
+ * @return a synchronized view of the specified map
+ */
+ public static <K, V> Map<K, V> map(Map<K, V> map, Object mutex) {
+ return new SynchronizedMap<K, V>(map, mutex);
+ }
+
+ /** @see Synchronized#map */
+ static class SynchronizedMap<K, V> extends SynchronizedObject
+ implements Map<K, V> {
+ private transient Set<K> keySet;
+ private transient Collection<V> values;
+ private transient Set<Map.Entry<K, V>> entrySet;
+
+ public SynchronizedMap(Map<K, V> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override protected Map<K, V> delegate() {
+ return (Map<K, V>) super.delegate();
+ }
+
+ public void clear() {
+ synchronized (mutex) {
+ delegate().clear();
+ }
+ }
+
+ public boolean containsKey(Object key) {
+ synchronized (mutex) {
+ return delegate().containsKey(key);
+ }
+ }
+
+ public boolean containsValue(Object value) {
+ synchronized (mutex) {
+ return delegate().containsValue(value);
+ }
+ }
+
+ public Set<Map.Entry<K, V>> entrySet() {
+ synchronized (mutex) {
+ if (entrySet == null) {
+ entrySet = set(delegate().entrySet(), mutex);
+ }
+ return entrySet;
+ }
+ }
+
+ public V get(Object key) {
+ synchronized (mutex) {
+ return delegate().get(key);
+ }
+ }
+
+ public boolean isEmpty() {
+ synchronized (mutex) {
+ return delegate().isEmpty();
+ }
+ }
+
+ public Set<K> keySet() {
+ synchronized (mutex) {
+ if (keySet == null) {
+ keySet = set(delegate().keySet(), mutex);
+ }
+ return keySet;
+ }
+ }
+
+ public V put(K key, V value) {
+ synchronized (mutex) {
+ return delegate().put(key, value);
+ }
+ }
+
+ public void putAll(Map<? extends K, ? extends V> map) {
+ synchronized (mutex) {
+ delegate().putAll(map);
+ }
+ }
+
+ public V remove(Object key) {
+ synchronized (mutex) {
+ return delegate().remove(key);
+ }
+ }
+
+ public int size() {
+ synchronized (mutex) {
+ return delegate().size();
+ }
+ }
+
+ public Collection<V> values() {
+ synchronized (mutex) {
+ if (values == null) {
+ values = collection(delegate().values(), mutex);
+ }
+ return values;
+ }
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ synchronized (mutex) {
+ return delegate().equals(o);
+ }
+ }
+
+ @Override public int hashCode() {
+ synchronized (mutex) {
+ return delegate().hashCode();
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns a synchronized (thread-safe) bimap backed by the specified bimap
+ * using the specified mutex. In order to guarantee serial access, it is
+ * critical that <b>all</b> access to the backing bimap is accomplished
+ * through the returned bimap.
+ *
+ * <p>It is imperative that the user manually synchronize on the specified
+ * mutex when accessing any of the return bimap's collection views:
+ *
+ * <pre>BiMap<K,V> m = Synchronized.biMap(
+ * new HashBiMap<K,V>(), mutex);
+ * ...
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (mutex) {
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
+ * while (i.hasNext()) {
+ * foo(i.next());
+ * }
+ * }</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * @param bimap the bimap to be wrapped in a synchronized view
+ * @return a synchronized view of the specified bimap
+ */
+ public static <K, V> BiMap<K, V> biMap(BiMap<K, V> bimap, Object mutex) {
+ return new SynchronizedBiMap<K, V>(bimap, mutex, null);
+ }
+
+ /** @see Synchronized#biMap */
+ static class SynchronizedBiMap<K, V> extends SynchronizedMap<K, V>
+ implements BiMap<K, V>, Serializable {
+ private transient Set<V> valueSet;
+ private transient BiMap<V, K> inverse;
+
+ public SynchronizedBiMap(
+ BiMap<K, V> delegate, Object mutex, BiMap<V, K> inverse) {
+ super(delegate, mutex);
+ this.inverse = inverse;
+ }
+
+ @Override protected BiMap<K, V> delegate() {
+ return (BiMap<K, V>) super.delegate();
+ }
+
+ @Override public Set<V> values() {
+ synchronized (mutex) {
+ if (valueSet == null) {
+ valueSet = set(delegate().values(), mutex);
+ }
+ return valueSet;
+ }
+ }
+
+ public V forcePut(K key, V value) {
+ synchronized (mutex) {
+ return delegate().forcePut(key, value);
+ }
+ }
+
+ public BiMap<V, K> inverse() {
+ synchronized (mutex) {
+ if (inverse == null) {
+ inverse
+ = new SynchronizedBiMap<V, K>(delegate().inverse(), mutex, this);
+ }
+ return inverse;
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see SynchronizedMultimap#asMap */
+ static class SynchronizedAsMap<K, V>
+ extends SynchronizedMap<K, Collection<V>> {
+ private transient Set<Map.Entry<K, Collection<V>>> asMapEntrySet;
+ private transient Collection<Collection<V>> asMapValues;
+
+ public SynchronizedAsMap(Map<K, Collection<V>> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override public Collection<V> get(Object key) {
+ synchronized (mutex) {
+ Collection<V> collection = super.get(key);
+ return (collection == null) ? null
+ : typePreservingCollection(collection, mutex);
+ }
+ }
+
+ @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
+ if (asMapEntrySet == null) {
+ asMapEntrySet = new SynchronizedAsMapEntries<K, V>(
+ delegate().entrySet(), mutex);
+ }
+ return asMapEntrySet;
+ }
+
+ @Override public Collection<Collection<V>> values() {
+ if (asMapValues == null) {
+ asMapValues
+ = new SynchronizedAsMapValues<V>(delegate().values(), mutex);
+ }
+ return asMapValues;
+ }
+
+ @Override public boolean containsValue(Object o) {
+ return values().contains(o);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /** @see SynchronizedMultimap#asMap */
+ static class SynchronizedAsMapValues<V>
+ extends SynchronizedCollection<Collection<V>> {
+ SynchronizedAsMapValues(Collection<Collection<V>> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override public Iterator<Collection<V>> iterator() {
+ // The iterator isn't synchronized, but its value is.
+ final Iterator<Collection<V>> iterator = super.iterator();
+ return new ForwardingIterator<Collection<V>>() {
+ @Override protected Iterator<Collection<V>> delegate() {
+ return iterator;
+ }
+ @Override public Collection<V> next() {
+ return typePreservingCollection(iterator.next(), mutex);
+ }
+ };
+ }
+
+ // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
+
+ @Override public Object[] toArray() {
+ synchronized (mutex) {
+ return ObjectArrays.toArrayImpl(delegate());
+ }
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ synchronized (mutex) {
+ return ObjectArrays.toArrayImpl(delegate(), array);
+ }
+ }
+ @Override public boolean contains(Object o) {
+ synchronized (mutex) {
+ return Iterators.contains(delegate().iterator(), o);
+ }
+ }
+ @Override public boolean containsAll(Collection<?> c) {
+ synchronized (mutex) {
+ return Collections2.containsAll(delegate(), c);
+ }
+ }
+ @Override public boolean remove(Object o) {
+ synchronized (mutex) {
+ return Iterables.remove(delegate(), o);
+ }
+ }
+ @Override public boolean removeAll(Collection<?> c) {
+ synchronized (mutex) {
+ return Iterators.removeAll(delegate().iterator(), c);
+ }
+ }
+ @Override public boolean retainAll(Collection<?> c) {
+ synchronized (mutex) {
+ return Iterators.retainAll(delegate().iterator(), c);
+ }
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultimap.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultimap.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultimap.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ * Implementation of {@code Multimap} whose keys and values are ordered by their
+ * natural ordering or by supplied comparators. When constructing a {@code
+ * TreeMultimap}, you may provide a {@link Comparator} for the keys, a {@code
+ * Comparator} for the values, both, or neither. If the keys or values lack an
+ * explicit {@code Comparator}, their natural ordering is used.
+ *
+ * <p>The collections returned by {@code keySet} and {@code asMap} iterate
+ * through the keys according to the key comparator ordering or the natural
+ * ordering of the keys. Similarly, {@code get}, {@code removeAll}, and {@code
+ * replaceValues} return collections that iterate through the values according
+ * to the value comparator ordering or the natural ordering of the values. The
+ * collections generated by {@code entries}, {@code keys}, and {@code values}
+ * iterate across the keys according to the above key ordering, and for each
+ * key they iterate across the values according to the value ordering.
+ *
+ * <p>The multimap does not store duplicate key-value pairs. Adding a new
+ * key-value pair equal to an existing key-value pair has no effect.
+ *
+ * <p>Depending on the comparators, null keys and values may or may not be
+ * supported. The natural ordering does not support nulls. All optional multimap
+ * methods are supported, and all returned views are modifiable.
+ *
+ * <p>This class is not threadsafe when any concurrent operations update the
+ * multimap. Concurrent read operations will work correctly. To allow concurrent
+ * update operations, wrap your multimap with a call to {@link
+ * Multimaps#synchronizedSortedSetMultimap}.
+ *
+ * @author Jared Levy
+ */
+public final class TreeMultimap<K, V> extends StandardSortedSetMultimap<K, V> {
+ private transient Comparator<? super K> keyComparator;
+ private transient Comparator<? super V> valueComparator;
+
+ /**
+ * Constructs an empty {@code TreeMultimap} using the natural ordering of the
+ * key and value classes. The key and value classes must satisfy the {@link
+ * Comparable} interface.
+ */
+ public TreeMultimap() {
+ this(null, null);
+ }
+
+ /**
+ * Constructs an empty {@code TreeMultimap} with explicit comparators.
+ *
+ * @param keyComparator the comparator that determines key ordering, or
+ * {@code null} for natural ordering
+ * @param valueComparator the comparator that determines value ordering, or
+ * {@code null} for natural ordering
+ */
+ public TreeMultimap(@Nullable Comparator<? super K> keyComparator,
+ @Nullable Comparator<? super V> valueComparator) {
+ super((keyComparator == null)
+ ? new TreeMap<K, Collection<V>>()
+ : new TreeMap<K, Collection<V>>(keyComparator));
+ this.keyComparator = keyComparator;
+ this.valueComparator = valueComparator;
+ }
+
+ /**
+ * Constructs a {@code TreeMultimap} with the same mappings as the specified
+ * multimap.
+ *
+ * <p>If the supplied multimap is an instance of {@code TreeMultimap}, the
+ * supplied multimap's key comparator is copied to the new instance.
+ * Otherwise, the new multimap uses the natural ordering of the keys, and the
+ * key class must satisfy the {@link Comparable} interface.
+ *
+ * <p>If the supplied multimap is a {@link SortedSetMultimap}, the supplied
+ * multimap's value comparator is copied to the new instance. Otherwise, the
+ * new multimap uses the natural ordering of the values, and the value class
+ * must satisfy the {@link Comparable} interface.
+ *
+ * @param multimap the multimap whose contents are copied to this multimap
+ */
+ @SuppressWarnings("unchecked")
+ public TreeMultimap(Multimap<? extends K, ? extends V> multimap) {
+ this((multimap instanceof TreeMultimap)
+ ? ((TreeMultimap<K, V>) multimap).keyComparator() : null,
+ (multimap instanceof SortedSetMultimap)
+ ? ((SortedSetMultimap<K, V>) multimap).valueComparator() : null,
+ multimap);
+ }
+
+ /**
+ * Constructs a {@code TreeMultimap} with explicit comparators and the same
+ * mappings as the specified multimap.
+ *
+ * @param keyComparator the comparator that determines key ordering, or
+ * {@code null} for natural ordering
+ * @param valueComparator the comparator that determines value ordering, or
+ * {@code null} for natural ordering
+ * @param multimap the multimap whose contents are copied to this multimap
+ */
+ public TreeMultimap(@Nullable Comparator<? super K> keyComparator,
+ @Nullable Comparator<? super V> valueComparator,
+ Multimap<? extends K, ? extends V> multimap) {
+ this(keyComparator, valueComparator);
+ putAll(multimap);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Creates an empty {@code TreeSet} for a collection of values for one key.
+ *
+ * @return a new {@code TreeSet} containing a collection of values for one
+ * key
+ */
+ @Override SortedSet<V> createCollection() {
+ return (valueComparator == null)
+ ? new TreeSet<V>() : new TreeSet<V>(valueComparator);
+ }
+
+ /**
+ * Returns the comparator that orders the multimap keys, with a {@code null}
+ * indicating that natural ordering is used.
+ */
+ public Comparator<? super K> keyComparator() {
+ return keyComparator;
+ }
+
+ public Comparator<? super V> valueComparator() {
+ return valueComparator;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code TreeMultimap} has unique sorted keys, this method
+ * returns a {@link SortedSet}, instead of the {@link Set} specified in the
+ * {@link Multimap} interface.
+ */
+ @Override public SortedSet<K> keySet() {
+ return (SortedSet<K>) super.keySet();
+ }
+
+ /**
+ * @serialData key comparator, value comparator, number of distinct keys, and
+ * then for each distinct key: the key, number of values for that key, and
+ * key values
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(keyComparator());
+ stream.writeObject(valueComparator());
+ Serialization.writeMultimap(this, stream);
+ }
+
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ keyComparator = (Comparator<? super K>) stream.readObject();
+ valueComparator = (Comparator<? super V>) stream.readObject();
+ setMap(new TreeMap<K, Collection<V>>(keyComparator));
+ Serialization.populateMultimap(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultiset.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultiset.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/TreeMultiset.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import org.richfaces.collections.base.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Multiset implementation backed by a {@code TreeMap}. The multiset elements
+ * are ordered by their natural sort ordering or by a comparator.
+ *
+ * @author Neal Kanodia
+ * @author Jared Levy
+ */
+@SuppressWarnings("serial") // we're overriding default serialization
+public final class TreeMultiset<E> extends AbstractMapBasedMultiset<E> {
+ /**
+ * Constructs a new, empty multiset, sorted according to the elements' natural
+ * order. All elements inserted into the multiset must implement the
+ * {@code Comparable} interface. Furthermore, all such elements must be
+ * <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
+ * {@code ClassCastException} for any elements {@code e1} and {@code e2} in
+ * the multiset. If the user attempts to add an element to the multiset that
+ * violates this constraint (for example, the user attempts to add a string
+ * element to a set whose elements are integers), the {@code add(Object)}
+ * call will throw a {@code ClassCastException}.
+ */
+ public TreeMultiset() {
+ super(new TreeMap<E, AtomicInteger>());
+ }
+
+ /**
+ * Constructs a new, empty multiset, sorted according to the specified
+ * comparator. All elements inserted into the multiset must be <i>mutually
+ * comparable</i> by the specified comparator: {@code comparator.compare(e1,
+ * e2)} must not throw a {@code ClassCastException} for any elements {@code
+ * e1} and {@code e2} in the multiset. If the user attempts to add an element
+ * to the multiset that violates this constraint, the {@code add(Object)} call
+ * will throw a {@code ClassCastException}.
+ *
+ * @param comparator the comparator that will be used to sort this multiset. A
+ * null value indicates that the elements' <i>natural ordering</i> should
+ * be used.
+ */
+ public TreeMultiset(Comparator<? super E> comparator) {
+ super(new TreeMap<E, AtomicInteger>(comparator));
+ }
+
+ /**
+ * Constructs an empty multiset containing the given initial elements, sorted
+ * according to the elements' natural order.
+ */
+ public TreeMultiset(Iterable<? extends E> elements) {
+ this();
+ Iterables.addAll(this, elements); // careful if we make this class non-final
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>In {@code TreeMultiset}, the return type of this method is narrowed
+ * from {@link Set} to {@link SortedSet}.
+ */
+ @Override public SortedSet<E> elementSet() {
+ return (SortedSet<E>) super.elementSet();
+ }
+
+ @Override public int count(@Nullable Object element) {
+ try {
+ return super.count(element);
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+ }
+
+ @Override public int removeAllOccurrences(@Nullable Object element) {
+ try {
+ return super.removeAllOccurrences(element);
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+ }
+
+ @Override protected Set<E> createElementSet() {
+ return new SortedMapBasedElementSet(
+ (SortedMap<E, AtomicInteger>) backingMap());
+ }
+
+ private class SortedMapBasedElementSet extends MapBasedElementSet
+ implements SortedSet<E> {
+
+ SortedMapBasedElementSet(SortedMap<E, AtomicInteger> map) {
+ super(map);
+ }
+
+ SortedMap<E, AtomicInteger> sortedMap() {
+ return (SortedMap<E, AtomicInteger>) getMap();
+ }
+
+ public Comparator<? super E> comparator() {
+ return sortedMap().comparator();
+ }
+
+ public E first() {
+ return sortedMap().firstKey();
+ }
+
+ public E last() {
+ return sortedMap().lastKey();
+ }
+
+ public SortedSet<E> headSet(E toElement) {
+ return new SortedMapBasedElementSet(sortedMap().headMap(toElement));
+ }
+
+ public SortedSet<E> subSet(E fromElement, E toElement) {
+ return new SortedMapBasedElementSet(
+ sortedMap().subMap(fromElement, toElement));
+ }
+
+ public SortedSet<E> tailSet(E fromElement) {
+ return new SortedMapBasedElementSet(sortedMap().tailMap(fromElement));
+ }
+ }
+
+ /*
+ * TODO: Decide whether entrySet() should return entries with an equals()
+ * method that calls the comparator to compare the two keys. If that change
+ * is made, AbstractMultiset.equals() can simply check whether two multisets
+ * have equal entry sets.
+ */
+
+ /**
+ * @serialData the comparator, the number of distinct elements, the first
+ * element, its count, the second element, its count, and so on
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(elementSet().comparator());
+ Serialization.writeMultiset(this, stream);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
+ Comparator<? super E> comparator
+ = (Comparator<? super E>) stream.readObject();
+ setBackingMap(new TreeMap<E, AtomicInteger>(comparator));
+ Serialization.populateMultiset(this, stream);
+ }
+
+ private static final long serialVersionUID = 0;
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/UnmodifiableIterator.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/UnmodifiableIterator.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/UnmodifiableIterator.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.richfaces.collections.collect;
+
+import java.util.Iterator;
+
+/**
+ * An iterator that does not support {@link #remove}.
+ *
+ * @author Jared Levy
+ */
+public abstract class UnmodifiableIterator<E> implements Iterator<E> {
+
+ /**
+ * Guaranteed to throw an exception and leave the underlying data unmodified.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public final void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/package-info.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/package-info.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/collections/collect/package-info.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * This package contains generic collection interfaces and implementations, and
+ * other utilities for working with collections.
+ *
+ * <h2>Collection Types</h2>
+ *
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.BiMap}
+ * <dd>An extension of {@link java.util.Map} that guarantees the uniqueness of
+ * its values as well as that of its keys. This is sometimes called an
+ * "invertible map," since the restriction on values enables it to support
+ * an {@linkplain org.richfaces.collections.collect.BiMap#inverse inverse view} --
+ * which is another instance of {@code BiMap}.
+ *
+ * <dt>{@link org.richfaces.collections.collect.Multiset}
+ * <dd>An extension of {@link java.util.Collection} that may contain duplicate
+ * values like a {@link java.util.List}, yet has order-independent equality
+ * like a {@link java.util.Set}. One typical use for a multiset is to
+ * represent a histogram.
+ *
+ * <dt>{@link org.richfaces.collections.collect.Multimap}
+ * <dd>A new type, which is similar to {@link java.util.Map}, but may contain
+ * multiple entries with the same key. Some behaviors of
+ * {@link org.richfaces.collections.collect.Multimap} are left unspecified and are
+ * provided only by the subtypes mentioned below.
+ *
+ * <dt>{@link org.richfaces.collections.collect.SetMultimap}
+ * <dd>An extension of {@link org.richfaces.collections.collect.Multimap} which has
+ * order-independent equality and does not allow duplicate entries; that is,
+ * while a key may appear twice in a {@code SetMultimap}, each must map to a
+ * different value. {@code SetMultimap} takes its name from the fact that
+ * the {@linkplain org.richfaces.collections.collect.SetMultimap#get collection of
+ * values} associated with a given key fulfills the {@link java.util.Set}
+ * contract.
+ *
+ * <dt>{@link org.richfaces.collections.collect.ListMultimap}
+ * <dd>An extension of {@link org.richfaces.collections.collect.Multimap} which permits
+ * duplicate entries, supports random access of values for a particular key,
+ * and has <i>partially order-dependent equality</i> as defined by
+ * {@link org.richfaces.collections.collect.ListMultimap#equals(Object)}. {@code
+ * ListMultimap} takes its name from the fact that the {@linkplain
+ * org.richfaces.collections.collect.ListMultimap#get collection of values}
+ * associated with a given key fulfills the {@link java.util.List} contract.
+ *
+ * <dt>{@link org.richfaces.collections.collect.SortedSetMultimap}
+ * <dd>An extension of {@link org.richfaces.collections.collect.SetMultimap} for which
+ * the {@linkplain org.richfaces.collections.collect.SortedSetMultimap#get
+ * collection values} associated with a given key is a
+ * {@link java.util.SortedSet}.
+ *
+ * <dt>{@link org.richfaces.collections.collect.ClassToInstanceMap}
+ * <dd>An extension of {@link java.util.Map} that associates a raw type with an
+ * instance of that type.
+ * </dl>
+ *
+ * <h2>Collection Implementations</h2>
+ *
+ * <h3>of {@link java.util.List}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ImmutableList}
+ * </ul>
+ *
+ * <h3>of {@link java.util.Set}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ImmutableSet}
+ * </ul>
+ *
+ * <h3>of {@link java.util.SortedSet}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ImmutableSortedSet}
+ * </dl>
+ *
+ * <h3>of {@link java.util.Map}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ImmutableMap}
+ * <dt>{@link org.richfaces.collections.collect.ReferenceMap}
+ * </ul>
+ *
+ * <h3>of {@link org.richfaces.collections.collect.BiMap}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.HashBiMap}
+ * <dt>{@link org.richfaces.collections.collect.EnumBiMap}
+ * <dt>{@link org.richfaces.collections.collect.EnumHashBiMap}
+ * </dl>
+ *
+ * <h3>of {@link org.richfaces.collections.collect.Multiset}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ConcurrentMultiset}
+ * <dt>{@link org.richfaces.collections.collect.EnumMultiset}
+ * <dt>{@link org.richfaces.collections.collect.HashMultiset}
+ * <dt>{@link org.richfaces.collections.collect.ImmutableMultiset}
+ * <dt>{@link org.richfaces.collections.collect.LinkedHashMultiset}
+ * <dt>{@link org.richfaces.collections.collect.TreeMultiset}
+ * </dl>
+ *
+ * <h3>of {@link org.richfaces.collections.collect.Multimap}</h3>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ArrayListMultimap}
+ * <dt>{@link org.richfaces.collections.collect.HashMultimap}
+ * <dt>{@link org.richfaces.collections.collect.ImmutableMultimap}
+ * <dt>{@link org.richfaces.collections.collect.LinkedHashMultimap}
+ * <dt>{@link org.richfaces.collections.collect.TreeMultimap}
+ * </dl>
+ *
+ * <h2>Skeletal implementations</h2>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.AbstractIterator}
+ * <dt>{@link org.richfaces.collections.collect.AbstractIterable}
+ * <dt>{@link org.richfaces.collections.collect.AbstractMapEntry}
+ * <dt>{@link org.richfaces.collections.collect.AbstractMultiset}
+ * <dt>{@link org.richfaces.collections.collect.AbstractMultisetEntry}
+ * <dt>{@link org.richfaces.collections.collect.AbstractRemovableIterator}
+ * <dt>{@link org.richfaces.collections.collect.UnmodifiableIterator}
+ * </dl>
+ *
+ * <h2>Classes of static utility methods</h2>
+ *
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.Collections2}
+ * <dt>{@link org.richfaces.collections.collect.Iterators}
+ * <dt>{@link org.richfaces.collections.collect.Iterables}
+ * <dt>{@link org.richfaces.collections.collect.Lists}
+ * <dt>{@link org.richfaces.collections.collect.Maps}
+ * <dt>{@link org.richfaces.collections.collect.Sets}
+ * <dt>{@link org.richfaces.collections.collect.Multisets}
+ * <dt>{@link org.richfaces.collections.collect.Multimaps}
+ * <dt>{@link org.richfaces.collections.collect.ObjectArrays}
+ * <dt>{@link org.richfaces.collections.collect.PrimitiveArrays}
+ * <dt>{@link org.richfaces.collections.collect.Serialization}
+ * </dl>
+
+ * <h2>Comparators</h2>
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.Comparators}
+ * <dt>{@link org.richfaces.collections.collect.Ordering}
+ * </ul>
+ *
+ * <h2>Constraints</h2>
+ *
+ * <dt>{@link org.richfaces.collections.collect.Constraint}
+ * <dt>{@link org.richfaces.collections.collect.Constraints}
+ * <dt>{@link org.richfaces.collections.collect.MapConstraint}
+ * <dt>{@link org.richfaces.collections.collect.MapConstraints}
+ *
+ * <h2>Forwarding collections</h2>
+ *
+ * <dl>
+ * <dt>{@link org.richfaces.collections.collect.ForwardingCollection }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingConcurrentMap }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingIterator }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingList }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingListIterator }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingMap }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingMapEntry }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingMultimap }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingMultiset }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingObject }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingQueue }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingSet }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingSortedMap }
+ * <dt>{@link org.richfaces.collections.collect.ForwardingSortedSet }
+ * </dl>
+ *
+ * <h2>Common Behavior</h2>
+ *
+ * <p>The methods of this package always throw {@link
+ * java.lang.NullPointerException} in response to a null value being supplied
+ * for any parameter that is not explicitly annotated as being {@link
+ * org.richfaces.collections.base.Nullable @Nullable}.
+ *
+ * @author Mike Bostock
+ * @author Kevin Bourrillion
+ * @author Jared Levy
+ */
+package org.richfaces.collections.collect;
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/HttpMethod.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/HttpMethod.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/HttpMethod.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,33 @@
+/**
+ *
+ */
+package org.richfaces.test;
+
+/**
+ * @author asmirnov
+ *
+ */
+public enum HttpMethod {
+
+ GET("GET"),
+ POST("POST"),
+ HEAD("HEAD"),
+ PUT("PUT"),
+ OPTIONS("OPTIONS"),
+ TRACE("TRACE"),
+ DELETE("DELETE");
+
+ /**
+ * @param name
+ */
+ private HttpMethod(String name) {
+ this.name = name;
+ }
+
+ private String name;
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/LocalServer.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/LocalServer.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/LocalServer.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,106 @@
+package org.richfaces.test;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+import org.richfaces.test.stub.ClasspathServerResource;
+import org.richfaces.test.stub.ServerResource;
+import org.richfaces.test.stub.ServerResourcePath;
+import org.richfaces.test.stub.ServerResourcesDirectory;
+import org.richfaces.test.stub.ServletContainer;
+import org.richfaces.test.stub.StaticServlet;
+import org.richfaces.test.stub.StubServletConfig;
+import org.richfaces.test.stub.StubServletContext;
+
+
+/**
+ * Hello world!
+ *
+ */
+public class LocalServer {
+
+ private List<ServletContainer> servlets = new ArrayList<ServletContainer>();
+
+ private ServletContainer defaultServlet;
+
+ private List<ServletContextListener> contextListeners = new ArrayList<ServletContextListener>();
+
+ private Map<String,String> initParameters=new HashMap<String, String>();
+
+ private ServerResource serverRoot = new ServerResourcesDirectory();
+
+ private StubServletContext context;
+
+
+ public void addServlet(String mapping,Servlet servlet){
+ servlets.add(new ServletContainer(mapping,servlet));
+ }
+
+ public ServletContainer getServlet(String path) {
+ ServletContainer result = defaultServlet;
+ for (ServletContainer servlet : servlets) {
+ if(servlet.isApplicable(path)){
+ result = servlet;
+ break;
+ }
+ }
+ return result;
+ }
+
+ public void addInitParameter(String name, String value) {
+ initParameters.put(name, value);
+ }
+
+ public void addResource(String path, String resource){
+ serverRoot.addResource(new ServerResourcePath(path), new ClasspathServerResource(resource));
+ }
+
+ public void addContextListener(ServletContextListener listener) {
+ contextListeners.add(listener);
+ }
+
+ public void init() throws ServletException {
+ // Create context.
+ this.context = new StubServletContext(serverRoot);
+ // Create init parameters
+ context.addInitParameters(initParameters);
+ // Inform listeners
+ for (ServletContextListener listener : contextListeners) {
+ listener.contextInitialized(new ServletContextEvent(context));
+ }
+ // Init servlets
+ for (ServletContainer servlet : servlets) {
+ // init servlet
+ servlet.init(this.context);
+ }
+ defaultServlet = new ServletContainer(null,new StaticServlet());
+ defaultServlet.init(getContext());
+
+ }
+
+ public void destroy(){
+ // Inform listeners
+ for (ServletContextListener listener : contextListeners) {
+ listener.contextDestroyed(new ServletContextEvent(context));
+ }
+
+ }
+
+ public ServerConnection getConnection(URL url) {
+ return new ServerConnection(this,url);
+ }
+
+ public StubServletContext getContext() {
+ return context;
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerConnection.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerConnection.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerConnection.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,238 @@
+/**
+ *
+ */
+package org.richfaces.test;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+
+import org.richfaces.test.stub.ServletContainer;
+import org.richfaces.test.stub.StubHttpRequest;
+import org.richfaces.test.stub.StubHttpResponse;
+import org.richfaces.test.stub.StubServletContext;
+
+/**
+ * This class represent single connection to the server.
+ * @author asmirnov
+ *
+ */
+public class ServerConnection {
+
+
+
+ private final LocalServer server;
+
+ private final URL url;
+
+ private ConnectionRequest request;
+
+ private ConnectionResponse response;
+
+ private final ServletContainer servlet;
+
+ private HttpMethod method= HttpMethod.GET;
+
+ private static final Cookie[] COOKIE = new Cookie[]{};
+
+ private List<Cookie> cookies = new ArrayList<Cookie>();
+
+ private Map<String, String[]> requestParameters = new HashMap<String, String[]>();
+
+
+ private final String pathInfo;
+
+ private final String servletPath;
+
+
+ public ServerConnection(LocalServer localServer, URL url) {
+ this.server = localServer;
+ this.url = url;
+ String path = url.getPath();
+ servlet = localServer.getServlet(path);
+ if(null == servlet){
+ throw new IllegalArgumentException();
+ }
+ this.pathInfo = servlet.getPathInfo(path);
+ this.servletPath = servlet.getServletPath(path);
+ this.request = new ConnectionRequest();
+ this.response = new ConnectionResponse();
+ this.request.setAttribute("javax.servlet.include.path_info", this.pathInfo);
+ this.request.setAttribute("javax.servlet.include.servlet_path", this.servletPath);
+ }
+
+
+ public void execute() throws ServletException, IOException {
+ this.servlet.execute(request,response);
+ }
+
+ /**
+ * @return the method
+ */
+ public HttpMethod getMethod() {
+ return method;
+ }
+
+ /**
+ * @param method the method to set
+ */
+ public void setMethod(HttpMethod method) {
+ this.method = method;
+ }
+
+ public void addRequestParameter(String name, String value) {
+ String[] values = requestParameters.get(name);
+ if(null == values){
+ values = new String[1];
+ } else {
+ String[] newValues= new String[values.length+1];
+ System.arraycopy(values, 0, newValues, 0, values.length);
+ values=newValues;
+ }
+ values[values.length-1]= value;
+ requestParameters.put(name, values);
+ }
+
+ /**
+ * @return the cookies
+ */
+ public List<Cookie> getCookies() {
+ return cookies;
+ }
+
+ /**
+ * @return the request
+ */
+ public ConnectionRequest getRequest() {
+ return request;
+ }
+
+ /**
+ * @return the response
+ */
+ public ConnectionResponse getResponse() {
+ return response;
+ }
+
+ private class ConnectionRequest extends StubHttpRequest {
+
+
+ public Cookie[] getCookies() {
+ // TODO Auto-generated method stub
+ return cookies.toArray(COOKIE);
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getMethod()
+ */
+ public String getMethod() {
+ return method.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getServletPath()
+ */
+ public String getServletPath() {
+ return servletPath;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getPathInfo()
+ */
+ public String getPathInfo() {
+ return pathInfo;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getQueryString()
+ */
+ public String getQueryString() {
+ return url.getQuery();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getRequestURI()
+ */
+ public String getRequestURI() {
+ return url.getPath();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
+ */
+ public String getParameter(String name) {
+ String[] values = requestParameters.get(name);
+ if(null != values && values.length>0){
+ return values[0];
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getParameterMap()
+ */
+ @SuppressWarnings("unchecked")
+ public Map getParameterMap() {
+ return Collections.unmodifiableMap(requestParameters);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getParameterNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getParameterNames() {
+ return Collections.enumeration(requestParameters.keySet());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
+ */
+ public String[] getParameterValues(String name) {
+ return requestParameters.get(name);
+ }
+
+
+
+ }
+
+ private class ConnectionResponse extends StubHttpResponse {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie
+ * )
+ */
+ public void addCookie(Cookie cookie) {
+ cookies.add(cookie);
+
+ }
+
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerLogger.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerLogger.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/ServerLogger.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+package org.richfaces.test;
+
+import java.util.logging.Logger;
+
+/**
+ * @author asmirnov
+ *
+ */
+public enum ServerLogger {
+
+ RESOURCE("resource"),
+ SERVER("server");
+
+ private static final String PREFIX="org.richfaces.test.";
+
+ private static final String LOGGING_BUNDLE="org.richfaces.test.LogMessages";
+ private final String name;
+
+ /**
+ * @param name
+ */
+ private ServerLogger(String name) {
+ this.name = PREFIX+name;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ public Logger getLogger(){
+ return Logger.getLogger(name, LOGGING_BUNDLE);
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/TestException.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/TestException.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/TestException.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,44 @@
+/**
+ *
+ */
+package org.richfaces.test;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class TestException extends RuntimeException {
+
+ /**
+ *
+ */
+ public TestException() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param message
+ */
+ public TestException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param cause
+ */
+ public TestException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public TestException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ClasspathServerResource.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ClasspathServerResource.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ClasspathServerResource.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,97 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletResponse;
+
+import org.richfaces.test.ServerLogger;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class ClasspathServerResource implements ServerResource {
+
+ private final String classpath;
+
+ private static final Logger log = ServerLogger.RESOURCE.getLogger();
+
+
+ /**
+ * @param name
+ * @param classpath
+ */
+ public ClasspathServerResource(String classpath) {
+ this.classpath = classpath;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#addResource(org.richfaces.test.stub.ServerResource)
+ */
+ public void addResource(ServerResourcePath path, ServerResource resource) {
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getResource(org.richfaces.test.stub.ServerResourcePath)
+ */
+ public ServerResource getResource(ServerResourcePath path) {
+ if(null == path){
+ throw new NullPointerException();
+ }
+ if(path.isFile()){
+ return this;
+ }
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getPaths()
+ */
+ public Set<String> getPaths() {
+ return Collections.emptySet();
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getAsStream()
+ */
+ public InputStream getAsStream() throws IOException {
+ URL url = getURL();
+ if (url != null) {
+ URLConnection connection = url.openConnection();
+ try {
+ connection.setUseCaches(false);
+ } catch (IllegalArgumentException e) {
+ log.info("RESOURCE_NOT_CACHEABLE");
+ }
+ return connection.getInputStream();
+ } else {
+ return null;
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getURL()
+ */
+ public URL getURL() {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if(null == classLoader){
+ classLoader = this.getClass().getClassLoader();
+ }
+ return classLoader.getResource(classpath);
+ }
+
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResource.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResource.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResource.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,50 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Set;
+
+/**
+ * @author asmirnov
+ *
+ */
+public interface ServerResource {
+
+
+ /**
+ * Get URL for a test server resource content. Directories should return null or "stub"
+ * @return
+ */
+ public URL getURL();
+
+ /**
+ * Create input stream to read content. Directories returns {@code null}
+ * @return
+ * @throws IOException
+ */
+ public InputStream getAsStream() throws IOException;
+
+ /**
+ * @return strings representing directory content. File-like resources return null.
+ */
+ public Set<String> getPaths();
+
+ /**
+ * Append resource to the current directory-like structure.
+ * @param path
+ * @param resource
+ */
+ public void addResource(ServerResourcePath path, ServerResource resource);
+
+ /**
+ * Get resource from the current directory or its subdirectories.
+ * @param path
+ * @return
+ */
+ public ServerResource getResource(ServerResourcePath path);
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcePath.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcePath.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcePath.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,100 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletContext;
+
+/**
+ * Class to represent web server resources directory path.
+ * @author asmirnov
+ *
+ */
+public class ServerResourcePath {
+
+ private static final Pattern SLASH = Pattern.compile("/");
+
+ public static final ServerResourcePath WEB_INF=new ServerResourcePath("/WEB-INF");
+
+ public static final ServerResourcePath META_INF=new ServerResourcePath("/META-INF");
+ public static final ServerResourcePath WEB_XML=new ServerResourcePath("/WEB-INF/web.xml");
+ public static final ServerResourcePath FACES_CONFIG=new ServerResourcePath("/WEB-INF/faces-config.xml");
+
+
+ private final String[] pathElements;
+
+ /**
+ * Private constructor for next sub - path.
+ * @param pathElements
+ */
+ private ServerResourcePath(String[] pathElements) {
+ this.pathElements = pathElements;
+ }
+
+ /**
+ * Create path from string representation. Path have to started with training slash, as required for
+ * {@link ServletContext#getResource(String)}
+ * @param path
+ */
+ public ServerResourcePath(String path) {
+ if (null == path) {
+ throw new NullPointerException();
+ }
+ if (!path.startsWith("/")) {
+ throw new IllegalArgumentException();
+ }
+ pathElements = SLASH.split(path);
+ }
+
+ /**
+ * Method to detect last element in the path.
+ * @return true for a last element in the path.
+ */
+ public boolean isFile() {
+ return pathElements.length <= 1;
+ }
+
+ /**
+ * Name of the next element ( directory or file ) name.
+ * For the "/foo/bar/baz" it should be "foo" , /bar/baz : "bar" , "/" : null.
+ * @return name of the next element or null if it is last element in the chain ( file ).
+ */
+ public String getNextElementName() {
+ if (pathElements.length > 1) {
+ return pathElements[1];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Create next path of the path chain.
+ * Path /foo/bar/baz should be converted to /bar/baz , /bar/baz -> /baz -> / ( empty path )
+ * @return next subdirectory path or null.
+ */
+ public ServerResourcePath getNextPath() {
+ if (pathElements.length > 1) {
+ String[] nextElenemts = new String[pathElements.length - 1];
+ System.arraycopy(pathElements, 1, nextElenemts, 0, nextElenemts.length);
+ return new ServerResourcePath(nextElenemts);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder();
+ if (pathElements.length > 1) {
+ for (int i = 1; i < pathElements.length; i++) {
+ String element = pathElements[i];
+ str.append("/").append(element);
+ }
+ } else {
+ str.append("/");
+ }
+ return str.toString();
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcesDirectory.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcesDirectory.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServerResourcesDirectory.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,86 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class ServerResourcesDirectory implements ServerResource {
+
+
+
+ private final Map<String,ServerResource> children = new HashMap<String,ServerResource>();
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#addResource(org.richfaces.test.stub.ServerResource)
+ */
+ public void addResource(ServerResourcePath path,ServerResource resource) {
+
+ if(null == path || path.isFile()){
+ throw new IllegalArgumentException();
+ } else if(path.getNextPath().isFile()) {
+ children.put(path.getNextElementName(), resource);
+ } else {
+ ServerResource nextDirectory = children.get(path.getNextElementName());
+ if(null == nextDirectory){
+ nextDirectory = new ServerResourcesDirectory();
+ children.put(path.getNextElementName(), nextDirectory);
+ }
+ nextDirectory.addResource(path.getNextPath(), resource);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getResource(org.richfaces.test.stub.ServerResourcePath)
+ */
+ public ServerResource getResource(ServerResourcePath path) {
+ if(null == path){
+ throw new NullPointerException();
+ }
+ ServerResource resource = null; //children.get(path.getName());
+ if(path.isFile()){
+ resource=this;
+ } else {
+ resource = children.get(path.getNextElementName());
+ if(!path.getNextPath().isFile() && null!=resource){
+ resource = resource.getResource(path.getNextPath());
+ }
+ }
+ return resource;
+ }
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getAsStream()
+ */
+ public InputStream getAsStream() {
+ // can't read directory.
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getPaths()
+ */
+ public Set<String> getPaths() {
+ return children.keySet();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.test.stub.ServerResource#getURL()
+ */
+ public URL getURL() {
+ // Directory don't have url.
+ return null;
+ }
+
+
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServletContainer.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServletContainer.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/ServletContainer.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,97 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+
+/**
+ * @author asmirnov
+ *
+ */
+public class ServletContainer {
+
+ private final Servlet servlet;
+
+ private final boolean prefixMapped;
+
+ private final String mapping;
+
+ private final Map<String, String> initParameters;
+
+ /**
+ * @param mapping
+ * @param servlet
+ */
+ public ServletContainer(String mapping, Servlet servlet, Map<String, String> initParameters) {
+ if(null == mapping){
+ this.prefixMapped = true;
+ this.mapping = "";
+ } else if (mapping.startsWith("*")) {
+ this.prefixMapped = false;
+ this.mapping = mapping.substring(1);
+ } else if (mapping.endsWith("*")) {
+ this.prefixMapped = true;
+ this.mapping = mapping.substring(0,mapping.length()-1);
+ } else {
+ throw new IllegalArgumentException("Invalid mapping "+mapping);
+ }
+ this.servlet = servlet;
+ this.initParameters = initParameters;
+ }
+
+ public ServletContainer(String mapping, Servlet servlet) {
+ this(mapping, servlet, Collections.<String, String>emptyMap());
+ }
+
+ public boolean isApplicable(String path) {
+ if(prefixMapped && path.startsWith(mapping)){
+ return true;
+ } else if(!prefixMapped && path.endsWith(mapping)){
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public String getServletPath(String path){
+ if (!isApplicable(path)) {
+ return null;
+ }
+ if(prefixMapped){
+ return mapping;
+ } else {
+ return path;
+ }
+ }
+
+ public String getPathInfo(String path) {
+ if (!isApplicable(path)) {
+ return null;
+ }
+ if(prefixMapped){
+ return path.substring(mapping.length());
+ } else {
+ return null;
+ }
+
+ }
+
+ public void init(StubServletContext context) throws ServletException {
+ StubServletConfig config = new StubServletConfig(context, this.initParameters);
+ servlet.init(config);
+ }
+
+ public void execute(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+ this.servlet.service(request, response);
+
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StaticServlet.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StaticServlet.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StaticServlet.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,44 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author asmirnov
+ *
+ */
+@SuppressWarnings("serial")
+public class StaticServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ InputStream inputStream = getServletContext().getResourceAsStream(req.getServletPath());
+ if(null != inputStream){
+ ServletOutputStream outputStream = resp.getOutputStream();
+ int c;
+ while((c = inputStream.read())>0){
+ outputStream.write(c);
+ }
+ inputStream.close();
+ outputStream.close();
+ } else {
+ resp.sendError(404, "not found");
+ }
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ doGet(req, resp);
+ }
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpRequest.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpRequest.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpRequest.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,483 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.richfaces.collections.collect.ImmutableCollection;
+import org.richfaces.collections.collect.ImmutableList;
+import org.richfaces.collections.collect.Multimap;
+import org.richfaces.collections.collect.Multimaps;
+
+/**
+ * @author asmirnov
+ *
+ */
+public abstract class StubHttpRequest implements HttpServletRequest {
+
+ public static final String LOCALHOST = "localhost";
+ public static final String HTTP = "http";
+ public static final String LOCALHOST_IP = "127.0.0.1";
+ public static final String UTF8 = "UTF-8";
+
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getAuthType()
+ */
+ public String getAuthType() {
+ // TODO configure test auth.
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getContextPath()
+ */
+ public String getContextPath() {
+ return StubServletContext.CONTEXT_PATH;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String)
+ */
+ public long getDateHeader(String name) {
+ // TODO create headers support
+ return -1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
+ */
+ public String getHeader(String name) {
+ // TODO create headers support
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getHeaderNames() {
+ // TODO create headers support
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getHeaders(String name) {
+ // TODO create headers support
+ return Collections.enumeration(Collections.EMPTY_LIST);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String)
+ */
+ public int getIntHeader(String name) {
+ // TODO create headers support
+ return -1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
+ */
+ public String getPathTranslated() {
+ // we have only 'virtual' server.
+ return null;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
+ */
+ public String getRemoteUser() {
+ // TODO configure test auth.
+ return null;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getRequestURL()
+ */
+ public StringBuffer getRequestURL() {
+ StringBuffer requestURL = new StringBuffer(HTTP + "://" + LOCALHOST
+ + getRequestURI());
+ return requestURL;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
+ */
+ public String getRequestedSessionId() {
+ return StubHttpSession.SESSION_ID;
+ }
+
+
+ private StubHttpSession session;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getSession()
+ */
+ public HttpSession getSession() {
+ if (session == null) {
+ session = new StubHttpSession();
+ }
+ return session;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
+ */
+ public HttpSession getSession(boolean create) {
+ if (session == null && create) {
+ session = new StubHttpSession();
+ }
+ return session;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
+ */
+ public Principal getUserPrincipal() {
+ // TODO implement test auth.
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
+ */
+ public boolean isRequestedSessionIdFromCookie() {
+ // test do not supports cookie
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
+ */
+ public boolean isRequestedSessionIdFromURL() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
+ */
+ public boolean isRequestedSessionIdFromUrl() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
+ */
+ public boolean isRequestedSessionIdValid() {
+ return session != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
+ */
+ public boolean isUserInRole(String role) {
+ // TODO implement test auth.
+ return false;
+ }
+
+ private Map<String, Object> attributes = new HashMap<String, Object>();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
+ */
+ public Object getAttribute(String name) {
+ return attributes.get(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getAttributeNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getAttributeNames() {
+ return Collections.enumeration(attributes.keySet());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getCharacterEncoding()
+ */
+ public String getCharacterEncoding() {
+ return UTF8;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getContentLength()
+ */
+ public int getContentLength() {
+ return -1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getContentType()
+ */
+ public String getContentType() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getInputStream()
+ */
+ public ServletInputStream getInputStream() throws IOException {
+ // TODO implement post stream.
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getLocalAddr()
+ */
+ public String getLocalAddr() {
+ return LOCALHOST_IP;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getLocalName()
+ */
+ public String getLocalName() {
+ return LOCALHOST;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getLocalPort()
+ */
+ public int getLocalPort() {
+ return 80;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getLocale()
+ */
+ public Locale getLocale() {
+ return Locale.US;
+ }
+
+ private final ImmutableCollection<Locale> locales = ImmutableList.of(
+ Locale.US, Locale.GERMANY);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getLocales()
+ */
+ public Enumeration getLocales() {
+ // TODO Auto-generated method stub
+ return Collections.enumeration(locales);
+ }
+
+ private String characterEncoding;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getProtocol()
+ */
+ public String getProtocol() {
+ return "HTTP/1.1";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getReader()
+ */
+ public BufferedReader getReader() throws IOException {
+ // TODO implements request buffer.
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getRealPath(java.lang.String)
+ */
+ public String getRealPath(String path) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getRemoteAddr()
+ */
+ public String getRemoteAddr() {
+ return LOCALHOST_IP;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getRemoteHost()
+ */
+ public String getRemoteHost() {
+ return LOCALHOST;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getRemotePort()
+ */
+ public int getRemotePort() {
+ return 1223340;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String)
+ */
+ public RequestDispatcher getRequestDispatcher(String path) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getScheme()
+ */
+ public String getScheme() {
+ return HTTP;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getServerName()
+ */
+ public String getServerName() {
+ return LOCALHOST;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#getServerPort()
+ */
+ public int getServerPort() {
+ return 80;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#isSecure()
+ */
+ public boolean isSecure() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
+ */
+ public void removeAttribute(String name) {
+ attributes.remove(name);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#setAttribute(java.lang.String,
+ * java.lang.Object)
+ */
+ public void setAttribute(String name, Object o) {
+ attributes.put(name, o);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
+ */
+ public void setCharacterEncoding(String env)
+ throws UnsupportedEncodingException {
+ this.characterEncoding=env;
+
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpResponse.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpResponse.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpResponse.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,402 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author asmirnov
+ *
+ */
+public abstract class StubHttpResponse implements HttpServletResponse {
+
+
+ private int status = 0;
+
+ private String redirectLocation = null;
+
+ private String errorMessage = null;
+
+ private int bufferSize = 8196;
+
+ private StringWriter outputWriter;
+
+ private ByteArrayOutputStream outputStream;
+
+ private PrintWriter printWriter;
+
+ private ServletOutputStream servletOutputStream;
+
+ private Locale locale = Locale.US;
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String,
+ * long)
+ */
+ public void addDateHeader(String name, long date) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String,
+ * java.lang.String)
+ */
+ public void addHeader(String name, String value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String,
+ * int)
+ */
+ public void addIntHeader(String name, int value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String)
+ */
+ public boolean containsHeader(String name) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String
+ * )
+ */
+ public String encodeRedirectURL(String url) {
+ return url;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#encodeRedirectUrl(java.lang.String
+ * )
+ */
+ public String encodeRedirectUrl(String url) {
+ // TODO Auto-generated method stub
+ return encodeRedirectURL(url);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String)
+ */
+ public String encodeURL(String url) {
+ return url;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#encodeUrl(java.lang.String)
+ */
+ public String encodeUrl(String url) {
+ return encodeURL(url);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#sendError(int)
+ */
+ public void sendError(int sc) throws IOException {
+ status = sc;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#sendError(int,
+ * java.lang.String)
+ */
+ public void sendError(int sc, String msg) throws IOException {
+ status = sc;
+ errorMessage = msg;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String)
+ */
+ public void sendRedirect(String location) throws IOException {
+ redirectLocation = location;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String,
+ * long)
+ */
+ public void setDateHeader(String name, long date) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String,
+ * java.lang.String)
+ */
+ public void setHeader(String name, String value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String,
+ * int)
+ */
+ public void setIntHeader(String name, int value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#setStatus(int)
+ */
+ public void setStatus(int sc) {
+ status = sc;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServletResponse#setStatus(int,
+ * java.lang.String)
+ */
+ public void setStatus(int sc, String sm) {
+ status = sc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#flushBuffer()
+ */
+ public void flushBuffer() throws IOException {
+ // do nothing
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#getBufferSize()
+ */
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#getCharacterEncoding()
+ */
+ public String getCharacterEncoding() {
+ return StubHttpRequest.UTF8;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#getContentType()
+ */
+ public String getContentType() {
+ return "text/html;charset=UTF-8";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#getLocale()
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#getOutputStream()
+ */
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (null != this.outputWriter) {
+ throw new IllegalStateException();
+ }
+ if (this.outputStream == null) {
+ this.outputStream = new ByteArrayOutputStream(getBufferSize());
+ servletOutputStream = new ServletOutputStream(){
+
+ @Override
+ public void write(int b) throws IOException {
+ StubHttpResponse.this.outputStream.write(b);
+ }
+
+ };
+ }
+ return servletOutputStream;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#getWriter()
+ */
+ public PrintWriter getWriter() throws IOException {
+ if (null != this.outputStream) {
+ throw new IllegalStateException();
+ }
+ if (this.outputWriter == null) {
+ this.outputWriter = new StringWriter(getBufferSize());
+ printWriter = new PrintWriter(outputWriter);
+ }
+ return printWriter;
+ }
+
+
+ public String getWriterContent() {
+ if(null != this.outputWriter){
+ return this.outputWriter.toString();
+ }
+ return null;
+ }
+
+ public byte[] getStreamContent() {
+ if(null!=outputStream){
+ return outputStream.toByteArray();
+ }
+ return null;
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#isCommitted()
+ */
+ public boolean isCommitted() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#reset()
+ */
+ public void reset() {
+ if(isCommitted()){
+ throw new IllegalStateException();
+ }
+ resetBuffer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#resetBuffer()
+ */
+ public void resetBuffer() {
+ if(isCommitted()){
+ throw new IllegalStateException();
+ }
+ this.servletOutputStream = null;
+ this.outputStream = null;
+ this.printWriter = null;
+ this.outputWriter = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#setBufferSize(int)
+ */
+ public void setBufferSize(int size) {
+ this.bufferSize = size;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String)
+ */
+ public void setCharacterEncoding(String charset) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#setContentLength(int)
+ */
+ public void setContentLength(int len) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#setContentType(java.lang.String)
+ */
+ public void setContentType(String type) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletResponse#setLocale(java.util.Locale)
+ */
+ public void setLocale(Locale loc) {
+ this.locale = loc;
+
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpSession.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpSession.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubHttpSession.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,156 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.util.Enumeration;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionContext;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class StubHttpSession implements HttpSession {
+
+ public static final String SESSION_ID="1234567890";
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String)
+ */
+ public Object getAttribute(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getAttributeNames()
+ */
+ public Enumeration getAttributeNames() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getCreationTime()
+ */
+ public long getCreationTime() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getId()
+ */
+ public String getId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getLastAccessedTime()
+ */
+ public long getLastAccessedTime() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
+ */
+ public int getMaxInactiveInterval() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getServletContext()
+ */
+ public ServletContext getServletContext() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getSessionContext()
+ */
+ public HttpSessionContext getSessionContext() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getValue(java.lang.String)
+ */
+ public Object getValue(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#getValueNames()
+ */
+ public String[] getValueNames() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#invalidate()
+ */
+ public void invalidate() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#isNew()
+ */
+ public boolean isNew() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#putValue(java.lang.String, java.lang.Object)
+ */
+ public void putValue(String name, Object value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#removeAttribute(java.lang.String)
+ */
+ public void removeAttribute(String name) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#removeValue(java.lang.String)
+ */
+ public void removeValue(String name) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#setAttribute(java.lang.String, java.lang.Object)
+ */
+ public void setAttribute(String name, Object value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpSession#setMaxInactiveInterval(int)
+ */
+ public void setMaxInactiveInterval(int interval) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletConfig.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletConfig.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletConfig.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,70 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class StubServletConfig implements ServletConfig {
+
+ public static final String FACES_SERVLET = "Faces Servlet";
+
+ private final ServletContext context;
+
+ private Map<String, String> initParameters ;
+
+
+
+ public StubServletConfig(ServletContext context) {
+ this.context = context;
+ this.initParameters = new HashMap<String, String>();
+ }
+
+ public StubServletConfig(ServletContext context,Map<String, String> initParameters) {
+ this.context = context;
+ this.initParameters = initParameters;
+ }
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
+ */
+ public String getInitParameter(String name) {
+ return initParameters.get(name);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletConfig#getInitParameterNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getInitParameterNames() {
+ return Collections.enumeration(initParameters.keySet());
+ }
+
+ public void setInitParameter(String name, String value) {
+ initParameters.put(name, value);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletConfig#getServletContext()
+ */
+ public ServletContext getServletContext() {
+ return context;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletConfig#getServletName()
+ */
+ public String getServletName() {
+ return FACES_SERVLET;
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletContext.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletContext.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/main/java/org/richfaces/test/stub/StubServletContext.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,267 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class StubServletContext implements ServletContext {
+
+ public static final String CONTEXT_PATH = "";
+ private final Map<String, Object> attributes = new HashMap<String, Object>();
+ private final ServerResource serverRoot;
+
+ private Map<String,String> initParameters = new HashMap<String, String>();
+
+ public StubServletContext(ServerResource serverRoot) {
+ this.serverRoot = serverRoot;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+ */
+ public Object getAttribute(String name) {
+ return attributes.get(name);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getAttributeNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getAttributeNames() {
+ return Collections.enumeration(attributes.keySet());
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getContext(java.lang.String)
+ */
+ public ServletContext getContext(String uripath) {
+ // stub server has only one context.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getContextPath()
+ */
+ public String getContextPath() {
+ // Test always run in the root context.
+ return CONTEXT_PATH;
+ }
+
+ public void addInitParameters(Map<String,String>parameters) {
+ initParameters.putAll(parameters);
+ }
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+ */
+ public String getInitParameter(String name) {
+ return initParameters.get(name);
+ }
+
+
+ /**
+ * Put new init parameter to the Map.
+ * @param name
+ * @param value
+ */
+ public void setInitParameter(String name, String value) {
+ initParameters.put(name, value);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getInitParameterNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getInitParameterNames() {
+ return Collections.enumeration(initParameters.keySet());
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getMajorVersion()
+ */
+ public int getMajorVersion() {
+ return 2;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+ */
+ public String getMimeType(String file) {
+ // TODO create mime-types table.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getMinorVersion()
+ */
+ public int getMinorVersion() {
+ return 5;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+ */
+ public RequestDispatcher getNamedDispatcher(String name) {
+ // TODO create stub dispatcher.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getRealPath(java.lang.String)
+ */
+ public String getRealPath(String path) {
+ // we always use 'virtual' configuration.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String)
+ */
+ public RequestDispatcher getRequestDispatcher(String path) {
+ // TODO implement stub dispatcher.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getResource(java.lang.String)
+ */
+ public URL getResource(String path) throws MalformedURLException {
+ URL url = null;
+ ServerResource resource = getServerResource(path);
+ if(null != resource){
+ url = resource.getURL();
+ }
+ return url;
+ }
+
+ /**
+ * @param path
+ * @return
+ */
+ protected ServerResource getServerResource(String path) {
+ return serverRoot.getResource(new ServerResourcePath(path));
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
+ */
+ public InputStream getResourceAsStream(String path) {
+ ServerResource resource = getServerResource(path);
+ if(null != resource){
+ try {
+ return resource.getAsStream();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
+ */
+ @SuppressWarnings("unchecked")
+ public Set getResourcePaths(String path) {
+ ServerResource resource = getServerResource(path);
+ if(null != resource){
+ return resource.getPaths();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getServerInfo()
+ */
+ public String getServerInfo() {
+ return "Stub test server";
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getServlet(java.lang.String)
+ */
+ public Servlet getServlet(String name) throws ServletException {
+ // always return null.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getServletContextName()
+ */
+ public String getServletContextName() {
+ // Stub server has no declared name.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getServletNames()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getServletNames() {
+ return Collections.enumeration(Collections.EMPTY_LIST);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#getServlets()
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getServlets() {
+ return Collections.enumeration(Collections.EMPTY_LIST);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#log(java.lang.String)
+ */
+ public void log(String msg) {
+ // TODO implement logging.
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#log(java.lang.Exception, java.lang.String)
+ */
+ public void log(Exception exception, String msg) {
+ // TODO implement logging.
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#log(java.lang.String, java.lang.Throwable)
+ */
+ public void log(String message, Throwable throwable) {
+ // TODO implement logging.
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+ */
+ public void removeAttribute(String name) {
+ attributes.remove(name);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
+ */
+ public void setAttribute(String name, Object object) {
+ attributes.put(name, object);
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/main/resources/org/richfaces/test/LogMessages.properties
===================================================================
Added: branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/FacesServerTest.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/FacesServerTest.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/FacesServerTest.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,77 @@
+/**
+ *
+ */
+package org.richfaces.test;
+
+import static org.junit.Assert.*;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.faces.webapp.FacesServlet;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.sun.faces.config.ConfigureListener;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class FacesServerTest {
+
+ private static ClassLoader contextClassLoader;
+
+ private static LocalServer facesServer;
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ contextClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(LocalServer.class.getClassLoader());
+ facesServer = new LocalServer();
+ facesServer.addServlet("*.jsf", new FacesServlet());
+ facesServer.addResource("/WEB-INF/web.xml", "org/richfaces/test/web.xml");
+ facesServer.addContextListener(new ConfigureListener());
+ facesServer.init();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ facesServer.destroy();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ /**
+ * Test method for {@link org.richfaces.test.LocalServer#getConnection(java.net.URL)}.
+ * @throws Exception
+ */
+ @Test
+ public void testGetConnection() throws Exception {
+ ServerConnection connection = facesServer.getConnection(new URL("http://localhost/index.jsf"));
+ connection.execute();
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourcePathTest.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourcePathTest.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourcePathTest.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,87 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class ServerResourcePathTest {
+
+ /**
+ * Test method for {@link org.richfaces.test.stub.ServerResourcePath#ServerResourcePath(java.lang.String)}.
+ */
+ @Test
+ public void testRootPath() {
+ ServerResourcePath path = new ServerResourcePath("/");
+ assertNull(path.getNextPath());
+ assertNull(path.getNextElementName());
+ assertTrue(path.isFile());
+ assertEquals("/", path.toString());
+ }
+
+ /**
+ * Test method for {@link org.richfaces.test.stub.ServerResourcePath#ServerResourcePath(java.lang.String)}.
+ */
+ @Test
+ public void testWebInfPath() {
+ ServerResourcePath path = ServerResourcePath.WEB_INF;
+ assertNotNull(path.getNextPath());
+ assertNotNull(path.getNextElementName());
+ assertFalse(path.isFile());
+ assertEquals("WEB-INF", path.getNextElementName());
+ assertEquals("/WEB-INF", path.toString());
+ path = path.getNextPath();
+ assertNotNull(path);
+ assertTrue(path.isFile());
+ path = path.getNextPath();
+ assertNull(path);
+ }
+
+ /**
+ * Test method for {@link org.richfaces.test.stub.ServerResourcePath#ServerResourcePath(java.lang.String)}.
+ */
+ @Test
+ public void testWebInfTrainingSlashPath() {
+ ServerResourcePath path = new ServerResourcePath("/WEB-INF/");
+ assertNotNull(path.getNextPath());
+ assertNotNull(path.getNextElementName());
+ assertFalse(path.isFile());
+ assertEquals("WEB-INF", path.getNextElementName());
+ assertEquals("/WEB-INF", path.toString());
+ path = path.getNextPath();
+ assertNotNull(path);
+ assertTrue(path.isFile());
+ path = path.getNextPath();
+ assertNull(path);
+ }
+
+
+ /**
+ * Test method for {@link org.richfaces.test.stub.ServerResourcePath#ServerResourcePath(java.lang.String)}.
+ */
+ @Test
+ public void testWebXmlPath() {
+ ServerResourcePath path = ServerResourcePath.WEB_XML;
+ assertFalse(path.isFile());
+ assertEquals("WEB-INF", path.getNextElementName());
+ assertEquals("/WEB-INF/web.xml", path.toString());
+ path = path.getNextPath();
+ assertNotNull(path.getNextElementName());
+ assertFalse(path.isFile());
+ assertEquals("web.xml", path.getNextElementName());
+ assertEquals("/web.xml", path.toString());
+ path = path.getNextPath();
+ assertNotNull(path);
+ assertTrue(path.isFile());
+ path = path.getNextPath();
+ assertNull(path);
+ }
+
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourceTest.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourceTest.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServerResourceTest.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,124 @@
+/**
+ *
+ */
+package org.richfaces.test.stub;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class ServerResourceTest {
+
+ private class MockResource implements ServerResource {
+
+ public void addResource(ServerResourcePath path, ServerResource resource) {
+ }
+
+ public InputStream getAsStream() throws IOException {
+ return null;
+ }
+
+ public Set<String> getPaths() {
+ return null;
+ }
+
+ public ServerResource getResource(ServerResourcePath path) {
+ if (null != path && path.isFile()) {
+ return this;
+ }
+ return null;
+ }
+
+ public URL getURL() {
+ return null;
+ }
+
+ }
+
+ /**
+ * Test method for
+ * {@link org.richfaces.test.stub.ServerResourcesDirectory#addResource(org.richfaces.test.stub.ServerResourcePath, org.richfaces.test.stub.ServerResource)}
+ * .
+ */
+ @Test
+ public void testAddResource() {
+ ServerResourcesDirectory root = new ServerResourcesDirectory();
+ MockResource webXml = new MockResource();
+ root.addResource(ServerResourcePath.WEB_XML, webXml);
+ assertEquals(1, root.getPaths().size());
+ MockResource facesConfig = new MockResource();
+ root.addResource(ServerResourcePath.FACES_CONFIG, facesConfig);
+ assertEquals(1, root.getPaths().size());
+ ServerResource webInf = root.getResource(ServerResourcePath.WEB_INF);
+ assertNotNull(webInf);
+ assertEquals(2, webInf.getPaths().size());
+ assertSame(webXml, webInf
+ .getResource(new ServerResourcePath("/web.xml")));
+ assertSame(facesConfig, webInf.getResource(new ServerResourcePath(
+ "/faces-config.xml")));
+ }
+
+ /**
+ * Test method for
+ * {@link org.richfaces.test.stub.ServerResourcesDirectory#getResource(org.richfaces.test.stub.ServerResourcePath)}
+ * .
+ */
+ @Test
+ public void testGetResource() {
+ ServerResourcesDirectory root = new ServerResourcesDirectory();
+ MockResource webXml = new MockResource();
+ root.addResource(ServerResourcePath.WEB_XML, webXml);
+ ServerResource webInf = root.getResource(ServerResourcePath.WEB_INF);
+ assertNotNull(webInf);
+ assertNull(root.getResource(new ServerResourcePath("/foo")));
+ assertNull(root.getResource(new ServerResourcePath("/foo/baz")));
+ assertEquals(1, root.getPaths().size());
+ assertNull(root.getResource(new ServerResourcePath(
+ "/WEB-INF/web.xml/foo")));
+ assertSame(webXml, webInf.getResource(new ServerResourcePath(
+ "/web.xml")));
+ }
+
+ /**
+ * Test method for
+ * {@link org.richfaces.test.stub.ServerResourcesDirectory#getAsStream()}.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testGetAsStream() throws IOException {
+ ClasspathServerResource resource = new ClasspathServerResource(
+ "org/richfaces/test/resource.txt");
+ InputStream inputStream = resource.getAsStream();
+ assertNotNull(inputStream);
+ try {
+ byte[] buff = new byte[20];
+ assertEquals(3, inputStream.read(buff));
+
+ } finally {
+ inputStream.close();
+ }
+ }
+
+
+ /**
+ * Test method for
+ * {@link org.richfaces.test.stub.ServerResourcesDirectory#getURL()}.
+ */
+ @Test
+ public void testGetURL() {
+ ClasspathServerResource resource = new ClasspathServerResource(
+ "org/richfaces/test/resource.txt");
+ assertNotNull(resource.getURL());
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServletTest.java
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServletTest.java (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/test/java/org/richfaces/test/stub/ServletTest.java 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,59 @@
+package org.richfaces.test.stub;
+
+import static org.junit.Assert.*;
+
+import javax.servlet.ServletException;
+
+import org.junit.Test;
+
+public class ServletTest {
+
+ @Test
+ public void testIsApplicable() {
+ StaticServlet staticServlet = new StaticServlet();
+ ServletContainer servlet = new ServletContainer("/foo/*",staticServlet);
+ assertTrue(servlet.isApplicable("/foo/bar.jsf"));
+ assertFalse(servlet.isApplicable("/foz/bar.jsf"));
+ assertFalse(servlet.isApplicable("bar"));
+ servlet = new ServletContainer("*.jsf",staticServlet);
+ assertTrue(servlet.isApplicable("/foo/bar.jsf"));
+ assertFalse(servlet.isApplicable("bar"));
+ try {
+ servlet = new ServletContainer(".jsf",staticServlet);
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ assertFalse(true);
+ }
+
+ @Test
+ public void testGetServletPath() {
+ StaticServlet staticServlet = new StaticServlet();
+ ServletContainer servlet = new ServletContainer("/foo/*",staticServlet);
+ assertEquals("/foo/", servlet.getServletPath("/foo/bar.jsf"));
+ assertNull(servlet.getServletPath("/foz/bar.jsf"));
+ servlet = new ServletContainer("*.jsf",staticServlet);
+ assertEquals("/foo/bar.jsf", servlet.getServletPath("/foo/bar.jsf"));
+ }
+
+ @Test
+ public void testGetPathInfo() {
+ StaticServlet staticServlet = new StaticServlet();
+ ServletContainer servlet = new ServletContainer("/foo/*",staticServlet);
+ assertEquals("bar.jsf", servlet.getPathInfo("/foo/bar.jsf"));
+ assertNull(servlet.getPathInfo("/foz/bar.jsf"));
+ servlet = new ServletContainer("*.jsf",staticServlet);
+ assertNull(servlet.getPathInfo("/foo/bar.jsf"));
+
+ }
+
+ @Test
+ public void testInit() throws ServletException {
+ StaticServlet staticServlet = new StaticServlet();
+ ServletContainer servlet = new ServletContainer("/foo/*",staticServlet);
+ StubServletContext context = new StubServletContext(new ServerResourcesDirectory());
+ servlet.init(context);
+ assertSame(context,staticServlet.getServletContext());
+ }
+
+}
Added: branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/resource.txt
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/resource.txt (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/resource.txt 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1 @@
+foo
\ No newline at end of file
Added: branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/web.xml
===================================================================
--- branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/web.xml (rev 0)
+++ branches/jsf2.0/framework/jsf-test/src/test/resources/org/richfaces/test/web.xml 2008-10-30 00:26:08 UTC (rev 10973)
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<web-app version="2.5"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
+
+ <display-name>Stub test</display-name>
+ <description>
+ Stub testing server
+ </description>
+ <context-param>
+ <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+
+ <!-- Faces Servlet -->
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ </servlet>
+
+
+ <!-- Faces Servlet Mapping -->
+
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.jsf</url-pattern>
+ </servlet-mapping>
+
+
+</web-app>
+
+
Modified: branches/jsf2.0/framework/pom.xml
===================================================================
--- branches/jsf2.0/framework/pom.xml 2008-10-29 20:26:23 UTC (rev 10972)
+++ branches/jsf2.0/framework/pom.xml 2008-10-30 00:26:08 UTC (rev 10973)
@@ -1,121 +1,116 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <artifactId>root</artifactId>
- <groupId>org.richfaces</groupId>
- <version>4.0.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.richfaces</groupId>
- <artifactId>framework</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>Java Server Faces AJAX framework</name>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-source</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <index>true</index>
- <manifest>
- <addDefaultSpecificationEntries>
- true
- </addDefaultSpecificationEntries>
- <addDefaultImplementationEntries>
- true
- </addDefaultImplementationEntries>
- </manifest>
- <manifestEntries>
- <mode>development</mode>
- <Build-Number>${buildNumber}</Build-Number>
- </manifestEntries>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- <version>1.1.14</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- <version>1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.0.4</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>jsp-api</artifactId>
- <version>2.1</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>jstl</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.sun.faces</groupId>
- <artifactId>mojarra-jsf-api</artifactId>
- <version>2.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>jsr250-api</artifactId>
- <version>1.0</version>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- </dependencies>
- <modules>
- <!--
- <module>api-parent</module> <module>impl-parent</module>
- -->
- <module>api</module>
- <module>impl</module>
- <module>test</module>
- </modules>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>root</artifactId>
+ <groupId>org.richfaces</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces</groupId>
+ <artifactId>framework</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Java Server Faces AJAX framework</name>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-source</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <index>true</index>
+ <manifest>
+ <addDefaultSpecificationEntries>
+ true
+ </addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>
+ true
+ </addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <mode>development</mode>
+ <Build-Number>${buildNumber}</Build-Number>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>jsp-api</artifactId>
+ <version>2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>jstl</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>2.0.0-b04</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>jsr250-api</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+ <modules>
+ <!--
+ <module>api-parent</module> <module>impl-parent</module>
+ -->
+ <module>api</module>
+ <module>impl</module>
+ <module>test</module>
+ <module>jsf-test</module>
+ </modules>
</project>
\ No newline at end of file
16 years, 2 months
JBoss Rich Faces SVN: r10972 - trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxSupport.
by richfaces-svn-commits@lists.jboss.org
Author: vmolotkov
Date: 2008-10-29 16:26:23 -0400 (Wed, 29 Oct 2008)
New Revision: 10972
Added:
trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxSupport/testUpdatingValue.xhtml
Log:
tests for a4j:support component
Added: trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxSupport/testUpdatingValue.xhtml
===================================================================
--- trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxSupport/testUpdatingValue.xhtml (rev 0)
+++ trunk/test-applications/seleniumTest/richfaces/src/main/webapp/pages/ajaxSupport/testUpdatingValue.xhtml 2008-10-29 20:26:23 UTC (rev 10972)
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets">
+<ui:composition template="../../template/caseTemplate.xhtml">
+ <ui:define name="caseName">testUpdatingValue</ui:define>
+ <ui:define name="caseBody">
+ <h:form id="_form">
+ <table cellpadding="5" >
+ <tr>
+ <td>1</td>
+ <td>
+ <h:inputText id="input_uv" value="#{ajaxSupport.inputValue}">
+ <a4j:support event="onkeyup" reRender="input_uv,data1_uv" action="#{ajaxSupport.updatingValueAction}"/>
+ </h:inputText>
+ </td>
+ <td><div><h:outputText style="font-weight: bold; border: 1px solid green" value="#{ajaxSupport.data}" id="data1_uv"></h:outputText></div></td>
+ </tr>
+ </table>
+ </h:form>
+ </ui:define>
+</ui:composition>
+</html>
16 years, 2 months
JBoss Rich Faces SVN: r10971 - in trunk/test-applications/seleniumTest/richfaces/src: test/java/org/richfaces/testng and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: vmolotkov
Date: 2008-10-29 16:25:56 -0400 (Wed, 29 Oct 2008)
New Revision: 10971
Modified:
trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/A4JSupport.java
trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxSupportTest.java
Log:
tests for a4j:support component
Modified: trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/A4JSupport.java
===================================================================
--- trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/A4JSupport.java 2008-10-29 17:24:47 UTC (rev 10970)
+++ trunk/test-applications/seleniumTest/richfaces/src/main/java/org/ajax4jsf/bean/A4JSupport.java 2008-10-29 20:25:56 UTC (rev 10971)
@@ -6,6 +6,11 @@
private String data = null;
+ /** property for testUpdatingValue */
+ private String inputValue = A4JSupport.Messages.INPUT_VALUE;
+
+
+
public static final String BEAN_NAME = "ajaxSupport";
public static class Messages {
@@ -22,6 +27,8 @@
public static final String TEST_PASSED = "test passed";
public static final String VALID_MESSAGE = "field is required";
+
+ public static final String INPUT_VALUE = "test";
}
public void linkListener (ActionEvent event) {
@@ -39,8 +46,11 @@
public void listener (ActionEvent event) {
data = Messages.FOR_SUBMIT;
}
+
+ public void updatingValueAction() {
+ data = inputValue;
+ }
-
/**
* @return the data
*/
@@ -54,5 +64,13 @@
public void setData(String data) {
this.data = data;
}
-
+
+ public String getInputValue() {
+ return inputValue;
+ }
+
+ public void setInputValue(String inputValue) {
+ this.inputValue = inputValue;
+ }
+
}
Modified: trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxSupportTest.java
===================================================================
--- trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxSupportTest.java 2008-10-29 17:24:47 UTC (rev 10970)
+++ trunk/test-applications/seleniumTest/richfaces/src/test/java/org/richfaces/testng/AjaxSupportTest.java 2008-10-29 20:25:56 UTC (rev 10971)
@@ -5,6 +5,7 @@
import org.ajax4jsf.bean.A4JSupport;
import org.ajax4jsf.template.Template;
+import org.bouncycastle.asn1.pkcs.KeyDerivationFunc;
import org.richfaces.SeleniumTestBase;
import org.richfaces.testng.util.CommonUtils;
import org.testng.Assert;
@@ -38,6 +39,8 @@
private static final String RENDERED_ATTRIBUTE_PAGE = "testRenderedAttribute.xhtml";
+ private static final String UPDATING_VALUE = "testUpdatingValue.xhtml";
+
private static final String DEFAULT_BEHAVIOUR_ID_PREFIX = "_db";
private static final String VALIDATION_FAILED_ID_PREFIX = "_vf";
@@ -56,6 +59,10 @@
private static final String RENDERED_ATTRIBUTE_ID_PREFIX = "_ra";
+ private static final String UPDATING_VALUE_ID_PREFIX = "_uv";
+
+ private static final String UPDATING_VALUE_KEY = "v";
+
private String testUrl;
private String parentFormId;
@@ -72,6 +79,8 @@
private String dataId2;
+ private String inputId;
+
/**
* action and actionListener defined as component attributes and actionListener
* defined as nested tag are invoked on the server after event of attached
@@ -213,6 +222,24 @@
checkBasicFunctionality(template, ENABLED_ATTRIBUTE_ID_PREFIX, false);
}
+
+ /**
+ *
+ * @param template
+ */
+ @Test
+ public void testUpdatingValue(Template template) {
+ setTestUrl(UPDATING_VALUE);
+ init(template);
+
+ String iid = inputId + UPDATING_VALUE_ID_PREFIX;
+ setValueById(iid, UPDATING_VALUE_KEY);
+ selenium.fireEvent("id="+iid, "keyup");
+ waitForAjaxCompletion();
+ AssertTextEquals(dataId1 + UPDATING_VALUE_ID_PREFIX, UPDATING_VALUE_KEY, CommonUtils.getFailedTestMessage(iid));
+ writeStatus(CommonUtils.getSuccessfulTestMessage(iid));
+ }
+
// /**
// * @see #testAjaxSupportComponent()
// *
@@ -317,6 +344,7 @@
validManagerId = parentFormId + "validManager";
dataId1 = parentFormId + "data1";
dataId2 = parentFormId + "data2";
+ inputId = parentFormId + "input";
}
@Override
16 years, 2 months
JBoss Rich Faces SVN: r10970 - trunk/ui/inplaceInput/src/main/templates.
by richfaces-svn-commits@lists.jboss.org
Author: vmolotkov
Date: 2008-10-29 13:24:47 -0400 (Wed, 29 Oct 2008)
New Revision: 10970
Modified:
trunk/ui/inplaceInput/src/main/templates/inplaceinput.jspx
Log:
component corrected
Modified: trunk/ui/inplaceInput/src/main/templates/inplaceinput.jspx
===================================================================
--- trunk/ui/inplaceInput/src/main/templates/inplaceinput.jspx 2008-10-29 17:01:23 UTC (rev 10969)
+++ trunk/ui/inplaceInput/src/main/templates/inplaceinput.jspx 2008-10-29 17:24:47 UTC (rev 10970)
@@ -173,7 +173,7 @@
},
changed:{
normal:'#{component.attributes["changedClass"]}',
- hovered:'#{component.attributes["changedHoverClass"]}',
+ hovered:'#{component.attributes["changedHoverClass"]}'
},
editable:'#{component.attributes["editClass"]}'
16 years, 2 months
JBoss Rich Faces SVN: r10969 - in tags: 3.1.6.SR1 and 131 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2008-10-29 13:01:23 -0400 (Wed, 29 Oct 2008)
New Revision: 10969
Added:
tags/3.1.6.SR1/
Modified:
tags/3.1.6.SR1/cdk/generator/pom.xml
tags/3.1.6.SR1/cdk/maven-archetype-jsf-component/pom.xml
tags/3.1.6.SR1/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml
tags/3.1.6.SR1/cdk/maven-archetype-jsfwebapp/pom.xml
tags/3.1.6.SR1/cdk/maven-cdk-plugin/pom.xml
tags/3.1.6.SR1/cdk/maven-javascript-plugin/pom.xml
tags/3.1.6.SR1/cdk/pom.xml
tags/3.1.6.SR1/docs/faq/en/pom.xml
tags/3.1.6.SR1/docs/faq/pom.xml
tags/3.1.6.SR1/docs/highlight/pom.xml
tags/3.1.6.SR1/docs/pom.xml
tags/3.1.6.SR1/docs/userguide/en/pom.xml
tags/3.1.6.SR1/docs/userguide/pom.xml
tags/3.1.6.SR1/docs/xslt/en/pom.xml
tags/3.1.6.SR1/docs/xslt/pom.xml
tags/3.1.6.SR1/extensions/gwt/pom.xml
tags/3.1.6.SR1/extensions/pom.xml
tags/3.1.6.SR1/extensions/seam/pom.xml
tags/3.1.6.SR1/extensions/trinidad/pom.xml
tags/3.1.6.SR1/framework/api-parent/pom.xml
tags/3.1.6.SR1/framework/api/pom.xml
tags/3.1.6.SR1/framework/impl-parent/pom.xml
tags/3.1.6.SR1/framework/impl/pom.xml
tags/3.1.6.SR1/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java
tags/3.1.6.SR1/framework/impl/src/main/java/org/richfaces/VersionBean.java
tags/3.1.6.SR1/framework/pom.xml
tags/3.1.6.SR1/framework/test/pom.xml
tags/3.1.6.SR1/pom.xml
tags/3.1.6.SR1/samples/calendar-sample/pom.xml
tags/3.1.6.SR1/samples/contextMenuDemo/pom.xml
tags/3.1.6.SR1/samples/dataFilterSliderDemo/pom.xml
tags/3.1.6.SR1/samples/dataTableDemo/pom.xml
tags/3.1.6.SR1/samples/datascroller-sample/pom.xml
tags/3.1.6.SR1/samples/dragDropDemo/pom.xml
tags/3.1.6.SR1/samples/dropdownmenu-sample/pom.xml
tags/3.1.6.SR1/samples/effect-sample/pom.xml
tags/3.1.6.SR1/samples/gmap-sample/pom.xml
tags/3.1.6.SR1/samples/inputNumberSliderDemo/pom.xml
tags/3.1.6.SR1/samples/inputNumberSpinnerDemo/pom.xml
tags/3.1.6.SR1/samples/jQuery-sample/pom.xml
tags/3.1.6.SR1/samples/listShuttleDemo/pom.xml
tags/3.1.6.SR1/samples/local-value-demo/pom.xml
tags/3.1.6.SR1/samples/modalpanel-sample/pom.xml
tags/3.1.6.SR1/samples/orderingListDemo/pom.xml
tags/3.1.6.SR1/samples/panel-sample/pom.xml
tags/3.1.6.SR1/samples/panelbar-sample/pom.xml
tags/3.1.6.SR1/samples/panelmenu-sample/pom.xml
tags/3.1.6.SR1/samples/pom.xml
tags/3.1.6.SR1/samples/portal-echo/pom.xml
tags/3.1.6.SR1/samples/rich-message-demo/pom.xml
tags/3.1.6.SR1/samples/richfaces-art-datatable/pom.xml
tags/3.1.6.SR1/samples/richfaces-demo/pom.xml
tags/3.1.6.SR1/samples/richfaces-ear-demo/ejb/pom.xml
tags/3.1.6.SR1/samples/richfaces-ear-demo/pom.xml
tags/3.1.6.SR1/samples/richfaces-ear-demo/richfacesEAR/pom.xml
tags/3.1.6.SR1/samples/richfaces-ear-demo/webapp/pom.xml
tags/3.1.6.SR1/samples/seamEAR/ear/pom.xml
tags/3.1.6.SR1/samples/seamEAR/ejbs/pom.xml
tags/3.1.6.SR1/samples/seamEAR/pom.xml
tags/3.1.6.SR1/samples/seamEAR/primary-source/pom.xml
tags/3.1.6.SR1/samples/seamEAR/projects/logging/pom.xml
tags/3.1.6.SR1/samples/seamEAR/projects/pom.xml
tags/3.1.6.SR1/samples/seamEAR/wars/pom.xml
tags/3.1.6.SR1/samples/seamEAR/wars/seamWebapp/pom.xml
tags/3.1.6.SR1/samples/seamIntegration/pom.xml
tags/3.1.6.SR1/samples/separator-sample/pom.xml
tags/3.1.6.SR1/samples/simpleTogglePanel-sample/pom.xml
tags/3.1.6.SR1/samples/skins/pom.xml
tags/3.1.6.SR1/samples/suggestionbox-sample/pom.xml
tags/3.1.6.SR1/samples/tabPanelDemo/pom.xml
tags/3.1.6.SR1/samples/togglePanel-sample/pom.xml
tags/3.1.6.SR1/samples/tomahawkCompability/pom.xml
tags/3.1.6.SR1/samples/toolBarDemo/pom.xml
tags/3.1.6.SR1/samples/tooltip-sample/pom.xml
tags/3.1.6.SR1/samples/tree-demo/pom.xml
tags/3.1.6.SR1/samples/treeModelDemo/pom.xml
tags/3.1.6.SR1/samples/useCases/pom.xml
tags/3.1.6.SR1/samples/virtualEarth-sample/pom.xml
tags/3.1.6.SR1/sandbox/api/pom.xml
tags/3.1.6.SR1/sandbox/impl/pom.xml
tags/3.1.6.SR1/sandbox/pom.xml
tags/3.1.6.SR1/sandbox/samples/dialog-window-sample/pom.xml
tags/3.1.6.SR1/sandbox/samples/panel2-sample/pom.xml
tags/3.1.6.SR1/sandbox/samples/pom.xml
tags/3.1.6.SR1/sandbox/samples/rich-message-demo/pom.xml
tags/3.1.6.SR1/sandbox/samples/simpleTogglePanel2-sample/pom.xml
tags/3.1.6.SR1/sandbox/ui/dialog-window/pom.xml
tags/3.1.6.SR1/sandbox/ui/panel2/pom.xml
tags/3.1.6.SR1/sandbox/ui/pom.xml
tags/3.1.6.SR1/sandbox/ui/simpleTogglePanel2/pom.xml
tags/3.1.6.SR1/sandbox/ui/state/pom.xml
tags/3.1.6.SR1/test-applications/facelets/pom.xml
tags/3.1.6.SR1/test-applications/jsp/pom.xml
tags/3.1.6.SR1/test-applications/pom.xml
tags/3.1.6.SR1/ui/assembly/pom.xml
tags/3.1.6.SR1/ui/calendar/pom.xml
tags/3.1.6.SR1/ui/componentControl/pom.xml
tags/3.1.6.SR1/ui/contextMenu/pom.xml
tags/3.1.6.SR1/ui/core/pom.xml
tags/3.1.6.SR1/ui/create.bat
tags/3.1.6.SR1/ui/dataFilterSlider/pom.xml
tags/3.1.6.SR1/ui/dataTable/pom.xml
tags/3.1.6.SR1/ui/datascroller/pom.xml
tags/3.1.6.SR1/ui/drag-drop/pom.xml
tags/3.1.6.SR1/ui/dropdown-menu/pom.xml
tags/3.1.6.SR1/ui/effect/pom.xml
tags/3.1.6.SR1/ui/gmap/pom.xml
tags/3.1.6.SR1/ui/inputnumber-slider/pom.xml
tags/3.1.6.SR1/ui/inputnumber-spinner/pom.xml
tags/3.1.6.SR1/ui/insert/pom.xml
tags/3.1.6.SR1/ui/jQuery/pom.xml
tags/3.1.6.SR1/ui/listShuttle/pom.xml
tags/3.1.6.SR1/ui/menu-components/pom.xml
tags/3.1.6.SR1/ui/message/pom.xml
tags/3.1.6.SR1/ui/modal-panel/pom.xml
tags/3.1.6.SR1/ui/orderingList/pom.xml
tags/3.1.6.SR1/ui/paint2D/pom.xml
tags/3.1.6.SR1/ui/panel/pom.xml
tags/3.1.6.SR1/ui/panelbar/pom.xml
tags/3.1.6.SR1/ui/panelmenu/pom.xml
tags/3.1.6.SR1/ui/pom.xml
tags/3.1.6.SR1/ui/scrollableDataTable/pom.xml
tags/3.1.6.SR1/ui/separator/pom.xml
tags/3.1.6.SR1/ui/simpleTogglePanel/pom.xml
tags/3.1.6.SR1/ui/spacer/pom.xml
tags/3.1.6.SR1/ui/suggestionbox/pom.xml
tags/3.1.6.SR1/ui/tabPanel/pom.xml
tags/3.1.6.SR1/ui/togglePanel/pom.xml
tags/3.1.6.SR1/ui/toolBar/pom.xml
tags/3.1.6.SR1/ui/tooltip/pom.xml
tags/3.1.6.SR1/ui/tree/pom.xml
tags/3.1.6.SR1/ui/treeModel/pom.xml
tags/3.1.6.SR1/ui/virtualEarth/pom.xml
Log:
Tagging 3.1.6.SR1 release
Copied: tags/3.1.6.SR1 (from rev 10963, tags/3.1.6.GA)
Modified: tags/3.1.6.SR1/cdk/generator/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/generator/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/generator/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>generator</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Java Server Faces component generator</name>
<build>
<plugins>
Modified: tags/3.1.6.SR1/cdk/maven-archetype-jsf-component/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/maven-archetype-jsf-component/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/maven-archetype-jsf-component/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,11 +2,11 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-archetype-jsf-component</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Archetype - maven-archetype-jsf-component</name>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -10,7 +10,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<configuration>
<library>
<prefix>${groupId}</prefix>
Modified: tags/3.1.6.SR1/cdk/maven-archetype-jsfwebapp/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/maven-archetype-jsfwebapp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/maven-archetype-jsfwebapp/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,11 +2,11 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-archetype-jsfwebapp</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Archetype for jsf webapp project</name>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/cdk/maven-cdk-plugin/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/maven-cdk-plugin/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/maven-cdk-plugin/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>maven-plugin</packaging>
<name>Maven plugin for JSF components code generation</name>
<dependencies>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.richfaces.cdk</groupId>
<artifactId>generator</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/cdk/maven-javascript-plugin/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/maven-javascript-plugin/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/maven-javascript-plugin/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,7 +4,7 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-javascript-plugin</artifactId>
Modified: tags/3.1.6.SR1/cdk/pom.xml
===================================================================
--- tags/3.1.6.GA/cdk/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/cdk/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>cdk</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>pom</packaging>
<name>JSF Components Development kit</name>
<dependencies />
Modified: tags/3.1.6.SR1/docs/faq/en/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/faq/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/faq/en/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -5,12 +5,12 @@
<parent>
<groupId>org.richfaces.docs</groupId>
<artifactId>faq</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.richfaces.docs.faq</groupId>
<artifactId>${translation}</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>jdocbook</packaging>
<name>Richfaces Manual (${translation})</name>
Modified: tags/3.1.6.SR1/docs/faq/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/faq/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/faq/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,13 +2,13 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>faq</artifactId>
<packaging>pom</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>FAQ</name>
<description>Frequently asked questions</description>
<pluginRepositories>
Modified: tags/3.1.6.SR1/docs/highlight/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/highlight/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/highlight/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>highlight</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>RichFaces Code Highlighting</name>
<dependencyManagement>
Modified: tags/3.1.6.SR1/docs/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>docs</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Project documentation</name>
<packaging>pom</packaging>
<!-- setup repositories, to build documentation separate from Java projects -->
Modified: tags/3.1.6.SR1/docs/userguide/en/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/userguide/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/userguide/en/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -5,12 +5,12 @@
<parent>
<groupId>org.richfaces.docs</groupId>
<artifactId>userguide</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.richfaces.docs.userguide</groupId>
<artifactId>${translation}</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>jdocbook</packaging>
<name>Richfaces Manual (${translation})</name>
Modified: tags/3.1.6.SR1/docs/userguide/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/userguide/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/userguide/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,13 +2,13 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>userguide</artifactId>
<packaging>pom</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>User guide</name>
<description>RichFaces user guide</description>
<pluginRepositories>
Modified: tags/3.1.6.SR1/docs/xslt/en/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/xslt/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/xslt/en/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>xslt</artifactId>
<groupId>org.richfaces.docs</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs.xslt</groupId>
<artifactId>en</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>jar</packaging>
<name>Documentation stylesheets (English translation)</name>
<description>
Modified: tags/3.1.6.SR1/docs/xslt/pom.xml
===================================================================
--- tags/3.1.6.GA/docs/xslt/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/docs/xslt/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>xslt</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>pom</packaging>
<name>Documentation stylesheets</name>
<description>Docbook documentation stylesheets</description>
Modified: tags/3.1.6.SR1/extensions/gwt/pom.xml
===================================================================
--- tags/3.1.6.GA/extensions/gwt/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/extensions/gwt/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -3,7 +3,7 @@
<parent>
<artifactId>master</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -99,7 +99,7 @@
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>ajax4jsf</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>com.sun.facelets</groupId>
Modified: tags/3.1.6.SR1/extensions/pom.xml
===================================================================
--- tags/3.1.6.GA/extensions/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/extensions/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>extensions</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Richfaces extensions for a different environments</name>
<packaging>pom</packaging>
<modules>
Modified: tags/3.1.6.SR1/extensions/seam/pom.xml
===================================================================
--- tags/3.1.6.GA/extensions/seam/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/extensions/seam/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -35,7 +35,7 @@
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>ajax4jsf</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>jboss</groupId>
Modified: tags/3.1.6.SR1/extensions/trinidad/pom.xml
===================================================================
--- tags/3.1.6.GA/extensions/trinidad/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/extensions/trinidad/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -35,7 +35,7 @@
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>ajax4jsf</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.trinidad</groupId>
Modified: tags/3.1.6.SR1/framework/api/pom.xml
===================================================================
--- tags/3.1.6.GA/framework/api/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/api/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,13 +2,13 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
<name>Java Server Faces AJAX framework API</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<build>
<plugins>
<plugin>
Modified: tags/3.1.6.SR1/framework/api-parent/pom.xml
===================================================================
--- tags/3.1.6.GA/framework/api-parent/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/api-parent/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,13 +4,13 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<packaging>pom</packaging>
<artifactId>api-parent</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Java Server Faces AJAX framework API Dependencies</name>
<properties>
<jsfVersion>1.1</jsfVersion>
Modified: tags/3.1.6.SR1/framework/impl/pom.xml
===================================================================
--- tags/3.1.6.GA/framework/impl/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/impl/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -3,19 +3,19 @@
<parent>
<artifactId>impl-parent</artifactId>
<groupId>org.richfaces.framework</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<relativePath>../impl-parent/pom.xml</relativePath>
</parent>
-->
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Java Server Faces AJAX framework implementation</name>
<build>
<resources>
@@ -261,7 +261,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<profiles>
Modified: tags/3.1.6.SR1/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java
===================================================================
--- tags/3.1.6.GA/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java 2008-10-29 17:01:23 UTC (rev 10969)
@@ -324,8 +324,6 @@
if (null != logicalStates) {
if (null != id) {
restoredState = (Object[]) logicalStates.get(id);
- externalContext.getRequestMap().put(VIEW_SEQUENCE,
- id);
if (null == restoredState) {
if (_log.isDebugEnabled()) {
_log
@@ -336,6 +334,9 @@
// http://jira.jboss.com/jira/browse/RF-3542
// restoredState = (Object[]) logicalStates
// .get(logicalStates.lastKey());
+ } else {
+ externalContext.getRequestMap().put(VIEW_SEQUENCE,
+ id);
}
} else {
if (_log.isDebugEnabled()) {
Modified: tags/3.1.6.SR1/framework/impl/src/main/java/org/richfaces/VersionBean.java
===================================================================
--- tags/3.1.6.GA/framework/impl/src/main/java/org/richfaces/VersionBean.java 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/impl/src/main/java/org/richfaces/VersionBean.java 2008-10-29 17:01:23 UTC (rev 10969)
@@ -37,7 +37,7 @@
* Revision version, must be auto modified by CVS
*/
- public static final String REVISION = "6.GA";
+ public static final String REVISION = "6.SR1";
public static final String SCM_REVISION = " SVN $Revision$ $Date$";//$Revision$ $Date$";
public static final Version _version = new Version();
Modified: tags/3.1.6.SR1/framework/impl-parent/pom.xml
===================================================================
--- tags/3.1.6.GA/framework/impl-parent/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/impl-parent/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -5,12 +5,12 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>impl-parent</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>pom</packaging>
<name>
Java Server Faces AJAX framework implementation parent file
@@ -203,7 +203,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<properties>
Modified: tags/3.1.6.SR1/framework/pom.xml
===================================================================
--- tags/3.1.6.GA/framework/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>framework</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>pom</packaging>
<name>Java Server Faces AJAX framework</name>
<dependencies />
Modified: tags/3.1.6.SR1/framework/test/pom.xml
===================================================================
--- tags/3.1.6.GA/framework/test/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/framework/test/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-test</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Ajax4Jsf test framework</name>
<url>https://ajax4jsf.dev.java.net</url>
<dependencies>
@@ -42,7 +42,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
Modified: tags/3.1.6.SR1/pom.xml
===================================================================
--- tags/3.1.6.GA/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,7 +4,7 @@
<artifactId>root</artifactId>
<packaging>pom</packaging>
<name>Jboss RichFaces project</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<url>http://labs.jboss.com/jbossrichfaces</url>
<properties>
<snapshotRepository>
@@ -157,9 +157,9 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/tags/3.1.6.GA</connection>
- <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/tags/3.1.6.GA</developerConnection>
- <url>https://svn.jboss.org/repos/richfaces/tags/3.1.6.GA</url>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/tags/3.1.6.SR1</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/tags/3.1.6.SR1</developerConnection>
+ <url>https://svn.jboss.org/repos/richfaces/tags/3.1.6.SR1</url>
</scm>
<profiles>
<profile>
Modified: tags/3.1.6.SR1/samples/calendar-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/calendar-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/calendar-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,29 +2,29 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>calendar-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>calendar-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>calendar</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/contextMenuDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/contextMenuDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/contextMenuDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,44 +2,44 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>contextMenuDemo</artifactId>
<packaging>war</packaging>
<name>contextMenuDemo Maven Webapp</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<dependencies>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataTable</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>contextMenu</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>componentControl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/dataFilterSliderDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/dataFilterSliderDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/dataFilterSliderDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,29 +2,29 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>dataFilterSliderDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>dataFilterSliderDemo Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataFilterSlider</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/dataTableDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/dataTableDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/dataTableDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>dataTableDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<url>http://maven.apache.org</url>
@@ -18,12 +18,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataTable</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/datascroller-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/datascroller-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/datascroller-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>datascroller-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>datascroller</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/dragDropDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/dragDropDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/dragDropDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>dragDropDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>Drag/Drop demo app</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>drag-drop</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/dropdownmenu-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/dropdownmenu-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/dropdownmenu-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>dropdownmenu-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,17 +17,17 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dropdown-menu</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/effect-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/effect-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/effect-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>effect-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>effect Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>effect</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/gmap-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/gmap-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/gmap-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>gmap-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>gmap-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>gmap</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/inputNumberSliderDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/inputNumberSliderDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/inputNumberSliderDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>inputNumberSliderDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>inputnumber-slider</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/inputNumberSpinnerDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/inputNumberSpinnerDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/inputNumberSpinnerDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>inputNumberSpinnerDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>inputnumber-spinner</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/jQuery-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/jQuery-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/jQuery-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>jQuery-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>jQuery-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>jQuery</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/listShuttleDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/listShuttleDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/listShuttleDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.1.6.SR1/samples/local-value-demo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/local-value-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/local-value-demo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,24 +2,24 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>local-value-demo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>richfaces-local-value-demo Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/modalpanel-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/modalpanel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/modalpanel-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>modalpanel-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>modalpanel-sample Maven Webapp</name>
<dependencies>
Modified: tags/3.1.6.SR1/samples/orderingListDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/orderingListDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/orderingListDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
@@ -16,12 +16,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>orderingList</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/panel-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/panel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/panel-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,24 +2,24 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>panel-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>panel-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>panel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/panelbar-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/panelbar-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/panelbar-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>panelbar-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>panelbar</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/panelmenu-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/panelmenu-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/panelmenu-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -3,24 +3,24 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>panelmenu-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>panelmenu-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>panelmenu</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,14 +2,14 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>samples</artifactId>
<packaging>pom</packaging>
<name>RichFaces Components Examples</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<url>http://labs.jboss.com/jbossrichfaces/samples</url>
<properties>
<!-- -->
@@ -66,12 +66,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>com.sun.facelets</groupId>
@@ -360,7 +360,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<exclusions>
<exclusion>
<groupId>javax.faces</groupId>
Modified: tags/3.1.6.SR1/samples/portal-echo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/portal-echo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/portal-echo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -5,13 +5,13 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>portal-echo</artifactId>
<packaging>war</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<description>Ajax JSF sample portlet</description>
<build>
<defaultGoal>package</defaultGoal>
Modified: tags/3.1.6.SR1/samples/rich-message-demo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/rich-message-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/rich-message-demo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,29 +2,29 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>rich-message-demo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>rich-message-demo</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>message</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/richfaces-art-datatable/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/richfaces-art-datatable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/richfaces-art-datatable/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -3,19 +3,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>richfaces-art-datatable</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>richfaces-art-datatableDemo Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/richfaces-demo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/richfaces-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/richfaces-demo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>richfaces-demo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>richfaces-demo Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>com.uwyn</groupId>
@@ -24,7 +24,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/richfaces-ear-demo/ejb/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/richfaces-ear-demo/ejb/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/richfaces-ear-demo/ejb/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,14 +4,14 @@
<parent>
<artifactId>richfaces-ear-demo</artifactId>
<groupId>org.richfaces.samples</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>ejb</artifactId>
<packaging>ejb</packaging>
<name>ejb</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
@@ -23,7 +23,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<exclusions>
<exclusion>
<groupId>javax.faces</groupId>
Modified: tags/3.1.6.SR1/samples/richfaces-ear-demo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/richfaces-ear-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/richfaces-ear-demo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,14 +4,14 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>richfaces-ear-demo</artifactId>
<name>JSF 1.2/Jee5 enterprise application demo</name>
<packaging>pom</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<build>
<pluginManagement>
<plugins>
Modified: tags/3.1.6.SR1/samples/richfaces-ear-demo/richfacesEAR/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/richfaces-ear-demo/richfacesEAR/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/richfaces-ear-demo/richfacesEAR/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,32 +4,32 @@
<parent>
<artifactId>richfaces-ear-demo</artifactId>
<groupId>org.richfaces.samples</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>richfacesEAR</artifactId>
<name>richfacesEAR</name>
<packaging>ear</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>ejb</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>ejb</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<type>ejb-client</type>
</dependency>
<dependency>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>webapp</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<type>war</type>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/richfaces-ear-demo/webapp/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/richfaces-ear-demo/webapp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/richfaces-ear-demo/webapp/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,14 +4,14 @@
<parent>
<artifactId>richfaces-ear-demo</artifactId>
<groupId>org.richfaces.samples</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>webapp</artifactId>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<url>http://maven.apache.org</url>
<build>
<finalName>webapp</finalName>
@@ -48,17 +48,17 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<optional>true</optional>
</dependency>
<dependency>
@@ -71,7 +71,7 @@
<dependency>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
<artifactId>ejb</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<type>ejb-client</type>
<scope>provided</scope>
<optional>true</optional>
Modified: tags/3.1.6.SR1/samples/seamEAR/ear/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/ear/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/ear/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -6,18 +6,18 @@
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>ear</artifactId>
<packaging>ear</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>ear assembly</name>
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<exclusions>
<exclusion>
<groupId>javax.faces</groupId>
Modified: tags/3.1.6.SR1/samples/seamEAR/ejbs/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/ejbs/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/ejbs/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -6,12 +6,12 @@
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>ejbs</artifactId>
<packaging>ejb</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>enterprise java beans</name>
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<dependencies>
<dependency>
@@ -32,7 +32,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<exclusions>
<exclusion>
<groupId>javax.faces</groupId>
Modified: tags/3.1.6.SR1/samples/seamEAR/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -6,12 +6,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
-->
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<artifactId>seamEAR</artifactId>
<packaging>pom</packaging>
<name>seam EAR project</name>
@@ -58,23 +58,23 @@
org.richfaces.samples.seamEAR.projects
</groupId>
<artifactId>logging</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>primary-source</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples.seamEAR.wars</groupId>
<artifactId>seamWebapp</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>ejbs</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<type>ejb</type>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/seamEAR/primary-source/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/primary-source/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/primary-source/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<dependencies>
<dependency>
Modified: tags/3.1.6.SR1/samples/seamEAR/projects/logging/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/projects/logging/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/projects/logging/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -7,6 +7,6 @@
<parent>
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>projects</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
</project>
Modified: tags/3.1.6.SR1/samples/seamEAR/projects/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/projects/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/projects/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -1,14 +1,14 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.seamEAR</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<artifactId>projects</artifactId>
<packaging>pom</packaging>
<name>sub projects</name>
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modules>
<module>logging</module>
Modified: tags/3.1.6.SR1/samples/seamEAR/wars/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/wars/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/wars/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,11 +4,11 @@
<artifactId>wars</artifactId>
<packaging>pom</packaging>
<name>wars</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modules>
<module>seamWebapp</module>
Modified: tags/3.1.6.SR1/samples/seamEAR/wars/seamWebapp/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamEAR/wars/seamWebapp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamEAR/wars/seamWebapp/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>wars</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<build>
<finalName>seamWebapp</finalName>
@@ -42,17 +42,17 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: tags/3.1.6.SR1/samples/seamIntegration/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/seamIntegration/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/seamIntegration/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -5,14 +5,14 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamIntegration</artifactId>
<packaging>war</packaging>
<name>seamIntegration Maven Webapp</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<build>
<finalName>seamIntegration</finalName>
<plugins>
Modified: tags/3.1.6.SR1/samples/separator-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/separator-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/separator-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>separator-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>separator</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/simpleTogglePanel-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/simpleTogglePanel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/simpleTogglePanel-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>simpleTogglePanel-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>simpleTogglePanel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/skins/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/skins/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/skins/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.1.6.SR1/samples/suggestionbox-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/suggestionbox-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/suggestionbox-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>suggestionbox-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>suggestionbox-sample Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>suggestionbox</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/tabPanelDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/tabPanelDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/tabPanelDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>tabPanelDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,22 +17,22 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>tabPanel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>panel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/togglePanel-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/togglePanel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/togglePanel-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>togglePanel-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,17 +17,17 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>togglePanel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>panel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/tomahawkCompability/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/tomahawkCompability/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/tomahawkCompability/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -8,7 +8,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>tomahawkCompability</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>tomahawkCompability Maven Webapp</name>
<properties>
Modified: tags/3.1.6.SR1/samples/toolBarDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/toolBarDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/toolBarDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,12 +2,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>toolBarDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>webapp Maven Webapp</name>
<build>
@@ -17,12 +17,12 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>toolBar</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/samples/tooltip-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/tooltip-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/tooltip-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -3,29 +3,29 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>tooltip-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>tooltip-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>tooltip</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>componentControl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/samples/tree-demo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/tree-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/tree-demo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,29 +2,29 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>tree-demo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>tree-demo Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>tree</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>drag-drop</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/treeModelDemo/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/treeModelDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/treeModelDemo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,24 +2,24 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>treeModelDemo</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>Tree Model Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>treeModel</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>tree</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/samples/useCases/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/useCases/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/useCases/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -5,12 +5,12 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>useCases</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>useCases Maven Webapp</name>
<build>
Modified: tags/3.1.6.SR1/samples/virtualEarth-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/samples/virtualEarth-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/samples/virtualEarth-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -4,19 +4,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>virtualEarth-sample</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<packaging>war</packaging>
<name>gmap-sample Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>virtualEarth</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.1.6.SR1/sandbox/api/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/api/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/api/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,18 +2,18 @@
<parent>
<artifactId>sandbox</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-api</artifactId>
<name>Richfaces Sandbox API</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<dependencies>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
Modified: tags/3.1.6.SR1/sandbox/impl/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/impl/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/impl/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,28 +2,28 @@
<parent>
<artifactId>sandbox</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-impl</artifactId>
<name>Richfaces Sandbox Implementation</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<dependencies>
<dependency>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-api</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-test</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
Modified: tags/3.1.6.SR1/sandbox/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.1.6.SR1/sandbox/samples/dialog-window-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/samples/dialog-window-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/samples/dialog-window-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -15,12 +15,12 @@
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>dialog-window</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/sandbox/samples/panel2-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/samples/panel2-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/samples/panel2-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -15,12 +15,12 @@
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>panel2</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/sandbox/samples/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/samples/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/samples/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.richfaces</groupId>
<artifactId>samples</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.1.6.SR1/sandbox/samples/rich-message-demo/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/samples/rich-message-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/samples/rich-message-demo/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.demo</groupId>
@@ -13,17 +13,17 @@
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>message</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/sandbox/samples/simpleTogglePanel2-sample/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/samples/simpleTogglePanel2-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/samples/simpleTogglePanel2-sample/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -16,12 +16,12 @@
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>simpleTogglePanel2</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/sandbox/ui/dialog-window/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/ui/dialog-window/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/ui/dialog-window/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -39,12 +39,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/sandbox/ui/panel2/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/ui/panel2/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/ui/panel2/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/sandbox/ui/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/ui/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/ui/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -3,7 +3,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
Modified: tags/3.1.6.SR1/sandbox/ui/simpleTogglePanel2/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/ui/simpleTogglePanel2/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/ui/simpleTogglePanel2/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/sandbox/ui/state/pom.xml
===================================================================
--- tags/3.1.6.GA/sandbox/ui/state/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/sandbox/ui/state/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -37,7 +37,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/test-applications/facelets/pom.xml
===================================================================
--- tags/3.1.6.GA/test-applications/facelets/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/test-applications/facelets/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>test-applications</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.1.6.SR1/test-applications/jsp/pom.xml
===================================================================
--- tags/3.1.6.GA/test-applications/jsp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/test-applications/jsp/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>test-applications</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.1.6.SR1/test-applications/pom.xml
===================================================================
--- tags/3.1.6.GA/test-applications/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/test-applications/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<relativePath>../samples</relativePath>
</parent>
@@ -58,11 +58,11 @@
<groupId>org.richfaces</groupId>
<artifactId>test-applications</artifactId>
<packaging>pom</packaging>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>RichFaces Test Applications</name>
<properties>
- <rfVersion>3.1.6.GA</rfVersion>
+ <rfVersion>3.1.6.SR1</rfVersion>
</properties>
<modules>
Modified: tags/3.1.6.SR1/ui/assembly/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/assembly/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/assembly/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -14,7 +14,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<configuration>
<library>
<prefix>org.richfaces</prefix>
Modified: tags/3.1.6.SR1/ui/calendar/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/calendar/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/calendar/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,13 +45,13 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>inputnumber-spinner</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/ui/componentControl/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/componentControl/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/componentControl/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/contextMenu/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/contextMenu/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/contextMenu/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>contextMenu</artifactId>
<name>contextMenu</name>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,12 +44,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/core/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/core/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/core/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/create.bat
===================================================================
--- tags/3.1.6.GA/ui/create.bat 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/create.bat 2008-10-29 17:01:23 UTC (rev 10969)
@@ -1 +1 @@
-mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.1.6.GA -DgroupId=org.richfaces -DartifactId=%1
\ No newline at end of file
+mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.1.6.SR1 -DgroupId=org.richfaces -DartifactId=%1
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/dataFilterSlider/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/dataFilterSlider/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/dataFilterSlider/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -14,7 +14,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/dataTable/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/dataTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/dataTable/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui-core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
-->
</dependencies>
Modified: tags/3.1.6.SR1/ui/datascroller/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/datascroller/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/datascroller/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/drag-drop/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/drag-drop/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/drag-drop/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui-core</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
-->
</dependencies>
Modified: tags/3.1.6.SR1/ui/dropdown-menu/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/dropdown-menu/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/dropdown-menu/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,12 +44,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/effect/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/effect/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/effect/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/gmap/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/gmap/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/gmap/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/inputnumber-slider/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/inputnumber-slider/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/inputnumber-slider/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/inputnumber-spinner/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/inputnumber-spinner/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/inputnumber-spinner/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
Modified: tags/3.1.6.SR1/ui/insert/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/insert/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/insert/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/jQuery/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/jQuery/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/jQuery/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/listShuttle/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/listShuttle/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/listShuttle/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
Modified: tags/3.1.6.SR1/ui/menu-components/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/menu-components/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/menu-components/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/message/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/message/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/message/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>message</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Message</name>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/modal-panel/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/modal-panel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/modal-panel/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/orderingList/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/orderingList/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/orderingList/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/paint2D/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/paint2D/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/paint2D/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/panel/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/panel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/panel/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/panelbar/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/panelbar/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/panelbar/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.1.6.SR1/ui/panelmenu/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/panelmenu/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/panelmenu/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -134,12 +134,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-test</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<scope>test</scope>
</dependency>
<dependency>
Modified: tags/3.1.6.SR1/ui/scrollableDataTable/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/scrollableDataTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/scrollableDataTable/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>scrollableDataTable</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<name>Scrollable Data Table</name>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -71,12 +71,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataTable</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<scope>test</scope>
</dependency>
</dependencies>
Modified: tags/3.1.6.SR1/ui/separator/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/separator/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/separator/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
Modified: tags/3.1.6.SR1/ui/simpleTogglePanel/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/simpleTogglePanel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/simpleTogglePanel/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/spacer/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/spacer/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/spacer/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/suggestionbox/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/suggestionbox/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/suggestionbox/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/tabPanel/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/tabPanel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/tabPanel/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/togglePanel/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/togglePanel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/togglePanel/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/toolBar/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/toolBar/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/toolBar/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/tooltip/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/tooltip/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/tooltip/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/tree/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/tree/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/tree/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>drag-drop</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/treeModel/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/treeModel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/treeModel/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,12 +45,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>tree</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.1.6.SR1/ui/virtualEarth/pom.xml
===================================================================
--- tags/3.1.6.GA/ui/virtualEarth/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.1.6.SR1/ui/virtualEarth/pom.xml 2008-10-29 17:01:23 UTC (rev 10969)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.1.6.GA</version>
+ <version>3.1.6.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
16 years, 2 months
JBoss Rich Faces SVN: r10968 - trunk/sandbox/ui/editor/src/main/java/org/richfaces/renderkit/resources.
by richfaces-svn-commits@lists.jboss.org
Author: alevkovsky
Date: 2008-10-29 12:23:42 -0400 (Wed, 29 Oct 2008)
New Revision: 10968
Modified:
trunk/sandbox/ui/editor/src/main/java/org/richfaces/renderkit/resources/EditorHTMLRenderer.java
Log:
RichEditor: adjust Faces suffix transferring
Modified: trunk/sandbox/ui/editor/src/main/java/org/richfaces/renderkit/resources/EditorHTMLRenderer.java
===================================================================
--- trunk/sandbox/ui/editor/src/main/java/org/richfaces/renderkit/resources/EditorHTMLRenderer.java 2008-10-29 14:50:25 UTC (rev 10967)
+++ trunk/sandbox/ui/editor/src/main/java/org/richfaces/renderkit/resources/EditorHTMLRenderer.java 2008-10-29 16:23:42 UTC (rev 10968)
@@ -144,18 +144,18 @@
String filterPrefix = webXml.getFacesFilterPrefix();
String filterSuffix = webXml.getFacesFilterSuffix();
if (filterPrefix != null) {
- return "";
+ return null;
}
if (filterSuffix != null) {
return filterSuffix;
}
if (prefix != null) {
- return "";
+ return null;
}
if (suffix != null) {
return suffix;
}
- return "";
+ return null;
}
/**
16 years, 2 months
JBoss Rich Faces SVN: r10967 - in tags: 3.2.2.SR1 and 178 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2008-10-29 10:50:25 -0400 (Wed, 29 Oct 2008)
New Revision: 10967
Added:
tags/3.2.2.SR1/
Modified:
tags/3.2.2.SR1/cdk/generator/pom.xml
tags/3.2.2.SR1/cdk/maven-archetype-jsf-component/pom.xml
tags/3.2.2.SR1/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml
tags/3.2.2.SR1/cdk/maven-archetype-jsfwebapp/pom.xml
tags/3.2.2.SR1/cdk/maven-archetype-jsfwebapp/src/main/resources/archetype-resources/pom.xml
tags/3.2.2.SR1/cdk/maven-archetype-plug-n-skin/pom.xml
tags/3.2.2.SR1/cdk/maven-archetype-plug-n-skin/src/main/resources/archetype-resources/pom.xml
tags/3.2.2.SR1/cdk/maven-cdk-plugin/pom.xml
tags/3.2.2.SR1/cdk/maven-javascript-plugin/pom.xml
tags/3.2.2.SR1/cdk/pom.xml
tags/3.2.2.SR1/docs/cdkguide/en/pom.xml
tags/3.2.2.SR1/docs/cdkguide/pom.xml
tags/3.2.2.SR1/docs/faq/en/pom.xml
tags/3.2.2.SR1/docs/faq/pom.xml
tags/3.2.2.SR1/docs/highlight/pom.xml
tags/3.2.2.SR1/docs/migrationguide/en/pom.xml
tags/3.2.2.SR1/docs/migrationguide/pom.xml
tags/3.2.2.SR1/docs/pom.xml
tags/3.2.2.SR1/docs/userguide/en/pom.xml
tags/3.2.2.SR1/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml
tags/3.2.2.SR1/docs/userguide/pom.xml
tags/3.2.2.SR1/docs/xslt/en/pom.xml
tags/3.2.2.SR1/docs/xslt/pom.xml
tags/3.2.2.SR1/extensions/gwt/pom.xml
tags/3.2.2.SR1/extensions/pom.xml
tags/3.2.2.SR1/extensions/seam/pom.xml
tags/3.2.2.SR1/extensions/trinidad/pom.xml
tags/3.2.2.SR1/framework/api/pom.xml
tags/3.2.2.SR1/framework/impl/pom.xml
tags/3.2.2.SR1/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java
tags/3.2.2.SR1/framework/impl/src/main/java/org/richfaces/VersionBean.java
tags/3.2.2.SR1/framework/pom.xml
tags/3.2.2.SR1/framework/test/pom.xml
tags/3.2.2.SR1/pom.xml
tags/3.2.2.SR1/samples/beanValidatorSample/pom.xml
tags/3.2.2.SR1/samples/calendar-sample/pom.xml
tags/3.2.2.SR1/samples/columnsDemo/pom.xml
tags/3.2.2.SR1/samples/combobox-sample/pom.xml
tags/3.2.2.SR1/samples/contextMenuDemo/pom.xml
tags/3.2.2.SR1/samples/darkX/pom.xml
tags/3.2.2.SR1/samples/dataFilterSliderDemo/pom.xml
tags/3.2.2.SR1/samples/dataTableDemo/pom.xml
tags/3.2.2.SR1/samples/datascroller-sample/pom.xml
tags/3.2.2.SR1/samples/dragDropDemo/pom.xml
tags/3.2.2.SR1/samples/dropdownmenu-sample/pom.xml
tags/3.2.2.SR1/samples/effect-sample/pom.xml
tags/3.2.2.SR1/samples/extendedDataTable-sample/pom.xml
tags/3.2.2.SR1/samples/fileUploadDemo/pom.xml
tags/3.2.2.SR1/samples/functions-demo/pom.xml
tags/3.2.2.SR1/samples/glassX/pom.xml
tags/3.2.2.SR1/samples/gmap-sample/pom.xml
tags/3.2.2.SR1/samples/hotKey-sample/pom.xml
tags/3.2.2.SR1/samples/inplaceInput-sample/pom.xml
tags/3.2.2.SR1/samples/inplaceSelect-sample/pom.xml
tags/3.2.2.SR1/samples/inputNumberSliderDemo/pom.xml
tags/3.2.2.SR1/samples/inputNumberSpinnerDemo/pom.xml
tags/3.2.2.SR1/samples/jQuery-sample/pom.xml
tags/3.2.2.SR1/samples/jira-data/pom.xml
tags/3.2.2.SR1/samples/laguna/pom.xml
tags/3.2.2.SR1/samples/listShuttleDemo/pom.xml
tags/3.2.2.SR1/samples/local-value-demo/pom.xml
tags/3.2.2.SR1/samples/modalpanel-sample/pom.xml
tags/3.2.2.SR1/samples/orderingListDemo/pom.xml
tags/3.2.2.SR1/samples/panel-sample/pom.xml
tags/3.2.2.SR1/samples/panelbar-sample/pom.xml
tags/3.2.2.SR1/samples/panelmenu-sample/pom.xml
tags/3.2.2.SR1/samples/pickList-sample/pom.xml
tags/3.2.2.SR1/samples/pom.xml
tags/3.2.2.SR1/samples/progressBarDemo/pom.xml
tags/3.2.2.SR1/samples/rich-message-demo/pom.xml
tags/3.2.2.SR1/samples/richfaces-art-datatable/pom.xml
tags/3.2.2.SR1/samples/richfaces-demo/pom.xml
tags/3.2.2.SR1/samples/richfaces-ear-demo/ejb/pom.xml
tags/3.2.2.SR1/samples/richfaces-ear-demo/pom.xml
tags/3.2.2.SR1/samples/richfaces-ear-demo/richfacesEAR/pom.xml
tags/3.2.2.SR1/samples/richfaces-ear-demo/webapp/pom.xml
tags/3.2.2.SR1/samples/scrollableDataTableDemo/pom.xml
tags/3.2.2.SR1/samples/seamEAR/ear/pom.xml
tags/3.2.2.SR1/samples/seamEAR/ejbs/pom.xml
tags/3.2.2.SR1/samples/seamEAR/pom.xml
tags/3.2.2.SR1/samples/seamEAR/primary-source/pom.xml
tags/3.2.2.SR1/samples/seamEAR/projects/logging/pom.xml
tags/3.2.2.SR1/samples/seamEAR/projects/pom.xml
tags/3.2.2.SR1/samples/seamEAR/wars/pom.xml
tags/3.2.2.SR1/samples/seamEAR/wars/seamWebapp/pom.xml
tags/3.2.2.SR1/samples/seamIntegration/pom.xml
tags/3.2.2.SR1/samples/separator-sample/pom.xml
tags/3.2.2.SR1/samples/simpleTogglePanel-sample/pom.xml
tags/3.2.2.SR1/samples/skins/pom.xml
tags/3.2.2.SR1/samples/sortingFilteringDemo/pom.xml
tags/3.2.2.SR1/samples/state-sample/pom.xml
tags/3.2.2.SR1/samples/stdcomponents-sample/pom.xml
tags/3.2.2.SR1/samples/suggestionbox-sample/pom.xml
tags/3.2.2.SR1/samples/tabPanelDemo/pom.xml
tags/3.2.2.SR1/samples/togglePanel-sample/pom.xml
tags/3.2.2.SR1/samples/tomahawkCompability/pom.xml
tags/3.2.2.SR1/samples/toolBarDemo/pom.xml
tags/3.2.2.SR1/samples/tooltip-sample/pom.xml
tags/3.2.2.SR1/samples/tree-demo/pom.xml
tags/3.2.2.SR1/samples/treeModelDemo/pom.xml
tags/3.2.2.SR1/samples/virtualEarth-sample/pom.xml
tags/3.2.2.SR1/sandbox/api/pom.xml
tags/3.2.2.SR1/sandbox/impl/pom.xml
tags/3.2.2.SR1/sandbox/pom.xml
tags/3.2.2.SR1/sandbox/samples/dialog-window-sample/pom.xml
tags/3.2.2.SR1/sandbox/samples/editor-sample/pom.xml
tags/3.2.2.SR1/sandbox/samples/fileUploadPOC/pom.xml
tags/3.2.2.SR1/sandbox/samples/panel2-sample/pom.xml
tags/3.2.2.SR1/sandbox/samples/pom.xml
tags/3.2.2.SR1/sandbox/samples/rex-demo/pom.xml
tags/3.2.2.SR1/sandbox/samples/simpleTogglePanel2-sample/pom.xml
tags/3.2.2.SR1/sandbox/ui/create.bat
tags/3.2.2.SR1/sandbox/ui/dialog-window/pom.xml
tags/3.2.2.SR1/sandbox/ui/editor/pom.xml
tags/3.2.2.SR1/sandbox/ui/panel2/pom.xml
tags/3.2.2.SR1/sandbox/ui/pom.xml
tags/3.2.2.SR1/sandbox/ui/rex-button/pom.xml
tags/3.2.2.SR1/sandbox/ui/rex-messageBox/pom.xml
tags/3.2.2.SR1/sandbox/ui/rex-resizable/pom.xml
tags/3.2.2.SR1/sandbox/ui/simpleTogglePanel2/pom.xml
tags/3.2.2.SR1/sandbox/ui/sortableHeader/pom.xml
tags/3.2.2.SR1/sandbox/ui/treeTable/pom.xml
tags/3.2.2.SR1/test-applications/facelets/pom.xml
tags/3.2.2.SR1/test-applications/jsp/pom.xml
tags/3.2.2.SR1/test-applications/pom.xml
tags/3.2.2.SR1/test-applications/seam/pom.xml
tags/3.2.2.SR1/test-applications/seleniumTest/pom.xml
tags/3.2.2.SR1/test-applications/seleniumTest/richfaces/pom.xml
tags/3.2.2.SR1/test-applications/seleniumTest/samples/pom.xml
tags/3.2.2.SR1/ui/assembly/pom.xml
tags/3.2.2.SR1/ui/beanValidator/pom.xml
tags/3.2.2.SR1/ui/calendar/pom.xml
tags/3.2.2.SR1/ui/columns/pom.xml
tags/3.2.2.SR1/ui/combobox/pom.xml
tags/3.2.2.SR1/ui/componentControl/pom.xml
tags/3.2.2.SR1/ui/contextMenu/pom.xml
tags/3.2.2.SR1/ui/core/pom.xml
tags/3.2.2.SR1/ui/create.bat
tags/3.2.2.SR1/ui/dataFilterSlider/pom.xml
tags/3.2.2.SR1/ui/dataTable/pom.xml
tags/3.2.2.SR1/ui/datascroller/pom.xml
tags/3.2.2.SR1/ui/drag-drop/pom.xml
tags/3.2.2.SR1/ui/dropdown-menu/pom.xml
tags/3.2.2.SR1/ui/effect/pom.xml
tags/3.2.2.SR1/ui/extendedDataTable/pom.xml
tags/3.2.2.SR1/ui/fileUpload/pom.xml
tags/3.2.2.SR1/ui/functions/pom.xml
tags/3.2.2.SR1/ui/gmap/pom.xml
tags/3.2.2.SR1/ui/hotKey/pom.xml
tags/3.2.2.SR1/ui/inplaceInput/pom.xml
tags/3.2.2.SR1/ui/inplaceSelect/pom.xml
tags/3.2.2.SR1/ui/inputnumber-slider/pom.xml
tags/3.2.2.SR1/ui/inputnumber-spinner/pom.xml
tags/3.2.2.SR1/ui/insert/pom.xml
tags/3.2.2.SR1/ui/jQuery/pom.xml
tags/3.2.2.SR1/ui/listShuttle/pom.xml
tags/3.2.2.SR1/ui/menu-components/pom.xml
tags/3.2.2.SR1/ui/message/pom.xml
tags/3.2.2.SR1/ui/modal-panel/pom.xml
tags/3.2.2.SR1/ui/orderingList/pom.xml
tags/3.2.2.SR1/ui/paint2D/pom.xml
tags/3.2.2.SR1/ui/panel/pom.xml
tags/3.2.2.SR1/ui/panelbar/pom.xml
tags/3.2.2.SR1/ui/panelmenu/pom.xml
tags/3.2.2.SR1/ui/pickList/pom.xml
tags/3.2.2.SR1/ui/pom.xml
tags/3.2.2.SR1/ui/progressBAR/pom.xml
tags/3.2.2.SR1/ui/scrollableDataTable/pom.xml
tags/3.2.2.SR1/ui/separator/pom.xml
tags/3.2.2.SR1/ui/simpleTogglePanel/pom.xml
tags/3.2.2.SR1/ui/spacer/pom.xml
tags/3.2.2.SR1/ui/state/pom.xml
tags/3.2.2.SR1/ui/suggestionbox/pom.xml
tags/3.2.2.SR1/ui/tabPanel/pom.xml
tags/3.2.2.SR1/ui/togglePanel/pom.xml
tags/3.2.2.SR1/ui/toolBar/pom.xml
tags/3.2.2.SR1/ui/tooltip/pom.xml
tags/3.2.2.SR1/ui/tree/pom.xml
tags/3.2.2.SR1/ui/treeModel/pom.xml
tags/3.2.2.SR1/ui/treeTable/pom.xml
tags/3.2.2.SR1/ui/virtualEarth/pom.xml
Log:
Copied: tags/3.2.2.SR1 (from rev 10963, tags/3.2.2.GA)
Modified: tags/3.2.2.SR1/cdk/generator/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/generator/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/generator/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>generator</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Java Server Faces component generator</name>
<build>
<plugins>
Modified: tags/3.2.2.SR1/cdk/maven-archetype-jsf-component/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-archetype-jsf-component/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-archetype-jsf-component/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,11 +2,11 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-archetype-jsf-component</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Archetype - maven-archetype-jsf-component</name>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-archetype-jsf-component/src/main/resources/archetype-resources/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -11,7 +11,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<configuration>
<library>
<prefix>${groupId}</prefix>
@@ -41,7 +41,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
Modified: tags/3.2.2.SR1/cdk/maven-archetype-jsfwebapp/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-archetype-jsfwebapp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-archetype-jsfwebapp/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,11 +2,11 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-archetype-jsfwebapp</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Archetype for jsf webapp project</name>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/cdk/maven-archetype-jsfwebapp/src/main/resources/archetype-resources/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-archetype-jsfwebapp/src/main/resources/archetype-resources/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-archetype-jsfwebapp/src/main/resources/archetype-resources/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -30,7 +30,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
Modified: tags/3.2.2.SR1/cdk/maven-archetype-plug-n-skin/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-archetype-plug-n-skin/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-archetype-plug-n-skin/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-archetype-plug-n-skin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Archetype - maven-archetype-plug-n-skin</name>
Modified: tags/3.2.2.SR1/cdk/maven-archetype-plug-n-skin/src/main/resources/archetype-resources/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-archetype-plug-n-skin/src/main/resources/archetype-resources/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-archetype-plug-n-skin/src/main/resources/archetype-resources/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -10,7 +10,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -34,7 +34,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Modified: tags/3.2.2.SR1/cdk/maven-cdk-plugin/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-cdk-plugin/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-cdk-plugin/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>maven-plugin</packaging>
<name>Maven plugin for JSF components code generation</name>
<dependencies>
@@ -55,7 +55,7 @@
<dependency>
<groupId>org.richfaces.cdk</groupId>
<artifactId>generator</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.2.2.SR1/cdk/maven-javascript-plugin/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/maven-javascript-plugin/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/maven-javascript-plugin/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -4,7 +4,7 @@
<parent>
<artifactId>cdk</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-javascript-plugin</artifactId>
Modified: tags/3.2.2.SR1/cdk/pom.xml
===================================================================
--- tags/3.2.2.GA/cdk/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/cdk/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>cdk</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>pom</packaging>
<name>JSF Components Development kit</name>
<dependencies />
Modified: tags/3.2.2.SR1/docs/cdkguide/en/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/cdkguide/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/cdkguide/en/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,12 +5,12 @@
<parent>
<groupId>org.richfaces.docs</groupId>
<artifactId>cdkguide</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.richfaces.docs.cdkguide</groupId>
<artifactId>${translation}</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>jar</packaging>
<name>Richfaces CDK Developer Guide (${translation})</name>
Modified: tags/3.2.2.SR1/docs/cdkguide/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/cdkguide/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/cdkguide/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>cdkguide</artifactId>
<packaging>pom</packaging>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>cdkguide</name>
<description>Richfaces CDK Developer Guide</description>
<pluginRepositories>
Modified: tags/3.2.2.SR1/docs/faq/en/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/faq/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/faq/en/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,12 +5,12 @@
<parent>
<groupId>org.richfaces.docs</groupId>
<artifactId>faq</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.richfaces.docs.faq</groupId>
<artifactId>${translation}</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>jar</packaging>
<name>Richfaces Manual (${translation})</name>
Modified: tags/3.2.2.SR1/docs/faq/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/faq/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/faq/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>faq</artifactId>
<packaging>pom</packaging>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>FAQ</name>
<description>Frequently asked questions</description>
<pluginRepositories>
Modified: tags/3.2.2.SR1/docs/highlight/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/highlight/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/highlight/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>highlight</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>RichFaces Code Highlighting</name>
<dependencyManagement>
Modified: tags/3.2.2.SR1/docs/migrationguide/en/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/migrationguide/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/migrationguide/en/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,12 +5,12 @@
<parent>
<groupId>org.richfaces.docs</groupId>
<artifactId>migration</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.richfaces.docs.migration</groupId>
<artifactId>${translation}</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>jar</packaging>
<name>RichFaces Migration Guide (${translation})</name>
Modified: tags/3.2.2.SR1/docs/migrationguide/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/migrationguide/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/migrationguide/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>migration</artifactId>
<packaging>pom</packaging>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Migration Guide</name>
<description>RichFaces Migration Guide from 3.1.* to 3.2.0 version</description>
<pluginRepositories>
Modified: tags/3.2.2.SR1/docs/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>docs</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Project documentation</name>
<packaging>pom</packaging>
<!-- setup repositories, to build documentation separate from Java projects -->
Modified: tags/3.2.2.SR1/docs/userguide/en/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/userguide/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/userguide/en/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,12 +5,12 @@
<parent>
<groupId>org.richfaces.docs</groupId>
<artifactId>userguide</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.richfaces.docs.userguide</groupId>
<artifactId>${translation}</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>jar</packaging>
<name>Richfaces Manual (${translation})</name>
Modified: tags/3.2.2.SR1/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml
===================================================================
--- tags/3.2.2.GA/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3158,7 +3158,7 @@
<listitem>
<para>
<code>DarchetypeVersion</code> indicates the RichFaces version. For example,
- <code>"3.2.2.GA"</code>
+ <code>"3.2.2.SR1"</code>
</para>
</listitem>
<listitem>
@@ -3455,7 +3455,7 @@
mvn archetype:create
-DarchetypeGroupId=org.richfaces.cdk
-DarchetypeArtifactId=maven-archetype-plug-n-skin
--DarchetypeVersion=3.2.2.GA
+-DarchetypeVersion=3.2.2.SR1
-DartifactId=P-n-S
-DgroupId=GROUPID
-Dversion=1.0.-SNAPSHOT
Modified: tags/3.2.2.SR1/docs/userguide/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/userguide/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/userguide/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>userguide</artifactId>
<packaging>pom</packaging>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>User guide</name>
<description>RichFaces user guide</description>
<pluginRepositories>
Modified: tags/3.2.2.SR1/docs/xslt/en/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/xslt/en/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/xslt/en/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>xslt</artifactId>
<groupId>org.richfaces.docs</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs.xslt</groupId>
<artifactId>en</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>jar</packaging>
<name>Documentation stylesheets (English translation)</name>
<description>
@@ -17,7 +17,7 @@
<dependency>
<groupId>org.richfaces.docs</groupId>
<artifactId>highlight</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
<build>
Modified: tags/3.2.2.SR1/docs/xslt/pom.xml
===================================================================
--- tags/3.2.2.GA/docs/xslt/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/docs/xslt/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>docs</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.docs</groupId>
<artifactId>xslt</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>pom</packaging>
<name>Documentation stylesheets</name>
<description>Docbook documentation stylesheets</description>
Modified: tags/3.2.2.SR1/extensions/gwt/pom.xml
===================================================================
--- tags/3.2.2.GA/extensions/gwt/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/extensions/gwt/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>extensions</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -99,7 +99,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>com.sun.facelets</groupId>
Modified: tags/3.2.2.SR1/extensions/pom.xml
===================================================================
--- tags/3.2.2.GA/extensions/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/extensions/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>extensions</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Richfaces extensions for a different environments</name>
<packaging>pom</packaging>
<modules>
Modified: tags/3.2.2.SR1/extensions/seam/pom.xml
===================================================================
--- tags/3.2.2.GA/extensions/seam/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/extensions/seam/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -35,7 +35,7 @@
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>ajax4jsf</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>jboss</groupId>
Modified: tags/3.2.2.SR1/extensions/trinidad/pom.xml
===================================================================
--- tags/3.2.2.GA/extensions/trinidad/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/extensions/trinidad/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -35,7 +35,7 @@
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>ajax4jsf</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.trinidad</groupId>
Modified: tags/3.2.2.SR1/framework/api/pom.xml
===================================================================
--- tags/3.2.2.GA/framework/api/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/framework/api/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
<name>Java Server Faces AJAX framework API</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
Modified: tags/3.2.2.SR1/framework/impl/pom.xml
===================================================================
--- tags/3.2.2.GA/framework/impl/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/framework/impl/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
<name>Java Server Faces AJAX framework implementation</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<resources>
<resource>
@@ -159,7 +159,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java
===================================================================
--- tags/3.2.2.GA/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/framework/impl/src/main/java/org/ajax4jsf/application/AjaxStateManager.java 2008-10-29 14:50:25 UTC (rev 10967)
@@ -39,7 +39,6 @@
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.StateManager;
-import javax.faces.application.StateManager.SerializedView;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
@@ -455,6 +454,11 @@
String id = restoreLogicalViewId(context, viewId, renderKitId);
StateHolder stateHolder = getStateHolder(context);
Object[] restoredState = stateHolder.getState(viewId, id);
+
+ if (restoredState != null && id != null) {
+ context.getExternalContext().getRequestMap().put(AJAX_VIEW_SEQUENCE, id);
+ }
+
return restoredState;
}
@@ -569,9 +573,6 @@
String id = (String) getRenderKit(context, renderKitId)
.getResponseStateManager().getTreeStructureToRestore(context,
viewId);
- if (null != id) {
- context.getExternalContext().getRequestMap().put(AJAX_VIEW_SEQUENCE, id);
- }
return id;
}
Modified: tags/3.2.2.SR1/framework/impl/src/main/java/org/richfaces/VersionBean.java
===================================================================
--- tags/3.2.2.GA/framework/impl/src/main/java/org/richfaces/VersionBean.java 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/framework/impl/src/main/java/org/richfaces/VersionBean.java 2008-10-29 14:50:25 UTC (rev 10967)
@@ -37,7 +37,7 @@
* Revision version, must be auto modified by CVS
*/
- public static final String REVISION = "2.GA" ;
+ public static final String REVISION = "2.SR1" ;
public static final String SCM_REVISION = " SVN $Revision$ $Date$";//$Revision$ $Date$";
public static final Version _version = new Version();
Modified: tags/3.2.2.SR1/framework/pom.xml
===================================================================
--- tags/3.2.2.GA/framework/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/framework/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>framework</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<packaging>pom</packaging>
<name>Java Server Faces AJAX framework</name>
<build>
Modified: tags/3.2.2.SR1/framework/test/pom.xml
===================================================================
--- tags/3.2.2.GA/framework/test/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/framework/test/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,12 +2,12 @@
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-test</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Ajax4Jsf test framework</name>
<url>https://ajax4jsf.dev.java.net</url>
<dependencies>
@@ -42,7 +42,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
Modified: tags/3.2.2.SR1/pom.xml
===================================================================
--- tags/3.2.2.GA/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -4,7 +4,7 @@
<artifactId>root</artifactId>
<packaging>pom</packaging>
<name>Jboss RichFaces project</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<url>http://labs.jboss.com/jbossrichfaces</url>
<properties>
<snapshotRepository>
@@ -199,9 +199,9 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:https://svn.jboss.org/repos/richfaces/tags/3.2.2.GA</connection>
- <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/branches/3.2.2.GA</developerConnection>
- <url>https://svn.jboss.org/repos/richfaces/branches/3.2.2.GA</url>
+ <connection>scm:svn:https://svn.jboss.org/repos/richfaces/tags/3.2.2.SR1</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/branches/3.2.2.SR1</developerConnection>
+ <url>https://svn.jboss.org/repos/richfaces/branches/3.2.2.SR1</url>
</scm>
<profiles>
<profile>
Modified: tags/3.2.2.SR1/samples/beanValidatorSample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/beanValidatorSample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/beanValidatorSample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,14 +3,14 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>beanValidatorSample</artifactId>
<packaging>war</packaging>
<name>beanValidatorSample Maven Webapp</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<finalName>beanValidatorSample</finalName>
<plugins>
@@ -33,7 +33,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>beanValidator</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -43,7 +43,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/samples/calendar-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/calendar-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/calendar-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/columnsDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/columnsDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/columnsDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/combobox-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/combobox-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/combobox-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/contextMenuDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/contextMenuDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/contextMenuDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/darkX/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/darkX/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/darkX/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -36,7 +36,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Modified: tags/3.2.2.SR1/samples/dataFilterSliderDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/dataFilterSliderDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/dataFilterSliderDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/dataTableDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/dataTableDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/dataTableDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/datascroller-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/datascroller-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/datascroller-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/dragDropDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/dragDropDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/dragDropDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/dropdownmenu-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/dropdownmenu-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/dropdownmenu-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/effect-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/effect-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/effect-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/extendedDataTable-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/extendedDataTable-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/extendedDataTable-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.2.2.SR1/samples/fileUploadDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/fileUploadDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/fileUploadDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/functions-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/functions-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/functions-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/glassX/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/glassX/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/glassX/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>glassX</artifactId>
<name>glassX</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -37,7 +37,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Modified: tags/3.2.2.SR1/samples/gmap-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/gmap-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/gmap-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/hotKey-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/hotKey-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/hotKey-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.2.2.SR1/samples/inplaceInput-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/inplaceInput-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/inplaceInput-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/inplaceSelect-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/inplaceSelect-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/inplaceSelect-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/inputNumberSliderDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/inputNumberSliderDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/inputNumberSliderDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/inputNumberSpinnerDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/inputNumberSpinnerDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/inputNumberSpinnerDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/jQuery-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/jQuery-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/jQuery-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/jira-data/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/jira-data/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/jira-data/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/laguna/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/laguna/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/laguna/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -4,7 +4,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<groupId>org.richfaces.samples</groupId>
@@ -16,7 +16,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<configuration>
<name>org.richfaces.laguna</name>
</configuration>
Modified: tags/3.2.2.SR1/samples/listShuttleDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/listShuttleDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/listShuttleDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/local-value-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/local-value-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/local-value-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/modalpanel-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/modalpanel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/modalpanel-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/orderingListDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/orderingListDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/orderingListDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/panel-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/panel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/panel-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/panelbar-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/panelbar-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/panelbar-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/panelmenu-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/panelmenu-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/panelmenu-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/pickList-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/pickList-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/pickList-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.2.2.SR1/samples/progressBarDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/progressBarDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/progressBarDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/rich-message-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/rich-message-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/rich-message-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/richfaces-art-datatable/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/richfaces-art-datatable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/richfaces-art-datatable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/richfaces-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/richfaces-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/richfaces-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -207,22 +207,22 @@
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>laguna</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>glassX</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>darkX</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>com.uwyn</groupId>
Modified: tags/3.2.2.SR1/samples/richfaces-ear-demo/ejb/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/richfaces-ear-demo/ejb/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/richfaces-ear-demo/ejb/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>richfaces-ear-demo</artifactId>
<groupId>org.richfaces.samples</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
Modified: tags/3.2.2.SR1/samples/richfaces-ear-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/richfaces-ear-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/richfaces-ear-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/richfaces-ear-demo/richfacesEAR/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/richfaces-ear-demo/richfacesEAR/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/richfaces-ear-demo/richfacesEAR/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>richfaces-ear-demo</artifactId>
<groupId>org.richfaces.samples</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
Modified: tags/3.2.2.SR1/samples/richfaces-ear-demo/webapp/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/richfaces-ear-demo/webapp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/richfaces-ear-demo/webapp/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>richfaces-ear-demo</artifactId>
<groupId>org.richfaces.samples</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples.richfaces-ear-demo</groupId>
Modified: tags/3.2.2.SR1/samples/scrollableDataTableDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/scrollableDataTableDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/scrollableDataTableDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>scrollableDataTableDemo</artifactId>
Modified: tags/3.2.2.SR1/samples/seamEAR/ear/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/ear/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/ear/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<dependencies>
<dependency>
Modified: tags/3.2.2.SR1/samples/seamEAR/ejbs/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/ejbs/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/ejbs/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<dependencies>
<dependency>
Modified: tags/3.2.2.SR1/samples/seamEAR/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/seamEAR/primary-source/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/primary-source/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/primary-source/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<dependencies>
<dependency>
Modified: tags/3.2.2.SR1/samples/seamEAR/projects/logging/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/projects/logging/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/projects/logging/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,6 +7,6 @@
<parent>
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>projects</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
</project>
Modified: tags/3.2.2.SR1/samples/seamEAR/projects/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/projects/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/projects/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modules>
<module>logging</module>
Modified: tags/3.2.2.SR1/samples/seamEAR/wars/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/wars/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/wars/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples</groupId>
<artifactId>seamEAR</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modules>
<module>seamWebapp</module>
Modified: tags/3.2.2.SR1/samples/seamEAR/wars/seamWebapp/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamEAR/wars/seamWebapp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamEAR/wars/seamWebapp/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -7,7 +7,7 @@
<parent>
<groupId>org.richfaces.samples.seamEAR</groupId>
<artifactId>wars</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<build>
<finalName>seamWebapp</finalName>
@@ -22,17 +22,17 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: tags/3.2.2.SR1/samples/seamIntegration/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/seamIntegration/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/seamIntegration/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,7 +5,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/separator-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/separator-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/separator-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/simpleTogglePanel-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/simpleTogglePanel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/simpleTogglePanel-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/skins/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/skins/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/skins/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/sortingFilteringDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/sortingFilteringDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/sortingFilteringDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
@@ -16,7 +16,7 @@
<!--dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>sortableHeader</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency-->
<dependency>
Modified: tags/3.2.2.SR1/samples/state-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/state-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/state-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -16,17 +16,17 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>state</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.samples</groupId>
<artifactId>skins</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/samples/stdcomponents-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/stdcomponents-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/stdcomponents-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/suggestionbox-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/suggestionbox-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/suggestionbox-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/tabPanelDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/tabPanelDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/tabPanelDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/togglePanel-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/togglePanel-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/togglePanel-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/tomahawkCompability/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/tomahawkCompability/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/tomahawkCompability/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/toolBarDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/toolBarDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/toolBarDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/tooltip-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/tooltip-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/tooltip-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/tree-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/tree-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/tree-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/treeModelDemo/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/treeModelDemo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/treeModelDemo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/samples/virtualEarth-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/samples/virtualEarth-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/samples/virtualEarth-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -4,7 +4,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
Modified: tags/3.2.2.SR1/sandbox/api/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/api/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/api/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,13 +2,13 @@
<parent>
<artifactId>sandbox</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-api</artifactId>
<name>Richfaces Sandbox API</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
@@ -25,12 +25,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
Modified: tags/3.2.2.SR1/sandbox/impl/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/impl/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/impl/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,28 +2,28 @@
<parent>
<artifactId>sandbox</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-impl</artifactId>
<name>Richfaces Sandbox Implementation</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<dependencies>
<dependency>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-api</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-test</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
Modified: tags/3.2.2.SR1/sandbox/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.2.2.SR1/sandbox/samples/dialog-window-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/dialog-window-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/dialog-window-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.2.2.SR1/sandbox/samples/editor-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/editor-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/editor-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.2.2.SR1/sandbox/samples/fileUploadPOC/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/fileUploadPOC/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/fileUploadPOC/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.2.2.SR1/sandbox/samples/panel2-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/panel2-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/panel2-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.2.2.SR1/sandbox/samples/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<groupId>org.richfaces</groupId>
<artifactId>samples</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.2.2.SR1/sandbox/samples/rex-demo/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/rex-demo/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/rex-demo/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
@@ -178,7 +178,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>com.uwyn</groupId>
@@ -193,28 +193,28 @@
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>rex-resizable</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>rex-button</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>rex-messageBox</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>componentControl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>richfaces-sandbox-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
Modified: tags/3.2.2.SR1/sandbox/samples/simpleTogglePanel2-sample/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/samples/simpleTogglePanel2-sample/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/samples/simpleTogglePanel2-sample/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
Modified: tags/3.2.2.SR1/sandbox/ui/create.bat
===================================================================
--- tags/3.2.2.GA/sandbox/ui/create.bat 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/create.bat 2008-10-29 14:50:25 UTC (rev 10967)
@@ -1 +1 @@
-mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.2.2.GA -DgroupId=org.richfaces.ui -DartifactId=%1
\ No newline at end of file
+mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.2.2.SR1 -DgroupId=org.richfaces.ui -DartifactId=%1
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/dialog-window/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/dialog-window/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/dialog-window/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -39,12 +39,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Modified: tags/3.2.2.SR1/sandbox/ui/editor/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/editor/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/editor/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/panel2/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/panel2/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/panel2/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -3,7 +3,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
Modified: tags/3.2.2.SR1/sandbox/ui/rex-button/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/rex-button/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/rex-button/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -43,7 +43,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/rex-messageBox/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/rex-messageBox/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/rex-messageBox/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -43,7 +43,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/rex-resizable/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/rex-resizable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/rex-resizable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/sandbox/ui/simpleTogglePanel2/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/simpleTogglePanel2/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/simpleTogglePanel2/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/sortableHeader/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/sortableHeader/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/sortableHeader/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces.sandbox</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>sortableHeader</artifactId>
<name>sortableHeader</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -52,17 +52,17 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataTable</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/sandbox/ui/treeTable/pom.xml
===================================================================
--- tags/3.2.2.GA/sandbox/ui/treeTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/sandbox/ui/treeTable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.sandbox</groupId>
<artifactId>treeTable</artifactId>
<name>treeTable</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/test-applications/facelets/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/facelets/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/facelets/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>test-applications</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.2.2.SR1/test-applications/jsp/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/jsp/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/jsp/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>test-applications</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: tags/3.2.2.SR1/test-applications/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<relativePath>../samples</relativePath>
</parent>
@@ -50,11 +50,11 @@
<groupId>org.richfaces</groupId>
<artifactId>test-applications</artifactId>
<packaging>pom</packaging>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>RichFaces Test Applications</name>
<properties>
- <rfVersion>3.2.2.GA</rfVersion>
+ <rfVersion>3.2.2.SR1</rfVersion>
</properties>
<modules>
Modified: tags/3.2.2.SR1/test-applications/seam/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/seam/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/seam/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,7 +5,7 @@
<parent>
<artifactId>test-applications</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.test-applications</groupId>
Modified: tags/3.2.2.SR1/test-applications/seleniumTest/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/seleniumTest/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/seleniumTest/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,14 +5,14 @@
<parent>
<artifactId>samples</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>seleniumTest</groupId>
<artifactId>seleniumTest</artifactId>
<packaging>pom</packaging>
<name>SeleniumTest</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<url>http://maven.apache.org</url>
<properties>
<http.port>8085</http.port>
@@ -217,7 +217,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
Modified: tags/3.2.2.SR1/test-applications/seleniumTest/richfaces/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/seleniumTest/richfaces/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/seleniumTest/richfaces/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,14 +5,14 @@
<parent>
<groupId>seleniumTest</groupId>
<artifactId>seleniumTest</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>seleniumTest</groupId>
<artifactId>richfaces</artifactId>
<packaging>war</packaging>
<name>seleniumTest Maven Webapp</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<finalName>seleniumTest</finalName>
<plugins>
Modified: tags/3.2.2.SR1/test-applications/seleniumTest/samples/pom.xml
===================================================================
--- tags/3.2.2.GA/test-applications/seleniumTest/samples/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/test-applications/seleniumTest/samples/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -5,13 +5,13 @@
<parent>
<groupId>seleniumTest</groupId>
<artifactId>seleniumTest</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>seleniumTest</groupId>
<artifactId>samples</artifactId>
<name>Samples</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<finalName>seleniumTest</finalName>
<plugins>
Modified: tags/3.2.2.SR1/ui/assembly/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/assembly/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/assembly/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -14,7 +14,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<configuration>
<library>
<prefix>org.richfaces</prefix>
Modified: tags/3.2.2.SR1/ui/beanValidator/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/beanValidator/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/beanValidator/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>beanValidator</artifactId>
<name>beanValidator</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
Modified: tags/3.2.2.SR1/ui/calendar/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/calendar/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/calendar/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,13 +45,13 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>inputnumber-spinner</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/columns/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/columns/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/columns/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
Modified: tags/3.2.2.SR1/ui/combobox/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/combobox/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/combobox/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>combobox</artifactId>
<name>combobox</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -51,12 +51,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>suggestionbox</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.2.2.SR1/ui/componentControl/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/componentControl/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/componentControl/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/contextMenu/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/contextMenu/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/contextMenu/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>contextMenu</artifactId>
<name>contextMenu</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -51,12 +51,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/core/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/core/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/core/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/create.bat
===================================================================
--- tags/3.2.2.GA/ui/create.bat 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/create.bat 2008-10-29 14:50:25 UTC (rev 10967)
@@ -1 +1 @@
-mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.2.2.GA -DgroupId=org.richfaces -DartifactId=%1
\ No newline at end of file
+mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.2.2.SR1 -DgroupId=org.richfaces -DartifactId=%1
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/dataFilterSlider/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/dataFilterSlider/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/dataFilterSlider/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -14,7 +14,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/dataTable/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/dataTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/dataTable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui-core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
-->
</dependencies>
Modified: tags/3.2.2.SR1/ui/datascroller/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/datascroller/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/datascroller/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/drag-drop/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/drag-drop/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/drag-drop/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui-core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
-->
</dependencies>
Modified: tags/3.2.2.SR1/ui/dropdown-menu/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/dropdown-menu/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/dropdown-menu/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,12 +44,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/effect/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/effect/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/effect/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/extendedDataTable/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/extendedDataTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/extendedDataTable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -64,45 +64,45 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>drag-drop</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataTable</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>menu-components</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>contextMenu</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>jQuery</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>componentControl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>scrollableDataTable</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/fileUpload/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/fileUpload/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/fileUpload/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>fileUpload</artifactId>
<name>fileUpload</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -51,12 +51,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>progressBar</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/functions/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/functions/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/functions/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/gmap/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/gmap/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/gmap/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/hotKey/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/hotKey/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/hotKey/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/inplaceInput/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/inplaceInput/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/inplaceInput/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>inplaceInput</artifactId>
<name>inplaceInput</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -51,17 +51,17 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>combobox</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/inplaceSelect/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/inplaceSelect/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/inplaceSelect/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>inplaceSelect</artifactId>
<name>inplaceSelect</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -51,22 +51,22 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>combobox</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>inplaceInput</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.2.2.SR1/ui/inputnumber-slider/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/inputnumber-slider/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/inputnumber-slider/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/inputnumber-spinner/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/inputnumber-spinner/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/inputnumber-spinner/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
Modified: tags/3.2.2.SR1/ui/insert/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/insert/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/insert/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/jQuery/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/jQuery/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/jQuery/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/listShuttle/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/listShuttle/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/listShuttle/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
Modified: tags/3.2.2.SR1/ui/menu-components/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/menu-components/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/menu-components/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/message/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/message/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/message/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>message</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<name>Message</name>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/modal-panel/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/modal-panel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/modal-panel/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/orderingList/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/orderingList/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/orderingList/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/paint2D/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/paint2D/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/paint2D/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/panel/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/panel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/panel/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/panelbar/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/panelbar/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/panelbar/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/panelmenu/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/panelmenu/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/panelmenu/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/pickList/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/pickList/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/pickList/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>pickList</artifactId>
<name>pickList</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -53,26 +53,26 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-api</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>listShuttle</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>orderingList</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
Modified: tags/3.2.2.SR1/ui/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>root</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -135,12 +135,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-test</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<scope>test</scope>
</dependency>
<dependency>
Modified: tags/3.2.2.SR1/ui/progressBAR/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/progressBAR/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/progressBAR/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
<artifactId>progressBar</artifactId>
<name>progressBar</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,12 +45,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/scrollableDataTable/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/scrollableDataTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/scrollableDataTable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -70,17 +70,17 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>dataTable</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>core</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/separator/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/separator/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/separator/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
Modified: tags/3.2.2.SR1/ui/simpleTogglePanel/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/simpleTogglePanel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/simpleTogglePanel/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/spacer/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/spacer/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/spacer/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/state/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/state/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/state/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -37,7 +37,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/suggestionbox/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/suggestionbox/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/suggestionbox/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/tabPanel/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/tabPanel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/tabPanel/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/togglePanel/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/togglePanel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/togglePanel/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/toolBar/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/toolBar/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/toolBar/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/tooltip/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/tooltip/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/tooltip/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -44,7 +44,7 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/tree/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/tree/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/tree/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>drag-drop</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/treeModel/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/treeModel/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/treeModel/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<id>generate-sources</id>
@@ -45,12 +45,12 @@
<dependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>tree</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: tags/3.2.2.SR1/ui/treeTable/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/treeTable/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/treeTable/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,19 +2,19 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
<artifactId>treeTable</artifactId>
<name>treeTable</name>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<build>
<plugins>
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
Modified: tags/3.2.2.SR1/ui/virtualEarth/pom.xml
===================================================================
--- tags/3.2.2.GA/ui/virtualEarth/pom.xml 2008-10-29 12:07:43 UTC (rev 10963)
+++ tags/3.2.2.SR1/ui/virtualEarth/pom.xml 2008-10-29 14:50:25 UTC (rev 10967)
@@ -2,7 +2,7 @@
<parent>
<artifactId>ui</artifactId>
<groupId>org.richfaces</groupId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.ui</groupId>
@@ -13,7 +13,7 @@
<plugin>
<groupId>org.richfaces.cdk</groupId>
<artifactId>maven-cdk-plugin</artifactId>
- <version>3.2.2.GA</version>
+ <version>3.2.2.SR1</version>
<executions>
<execution>
<phase>generate-sources</phase>
16 years, 2 months
JBoss Rich Faces SVN: r10966 - trunk/sandbox/samples/editorSeam-sample/src/main/webapp/WEB-INF.
by richfaces-svn-commits@lists.jboss.org
Author: alevkovsky
Date: 2008-10-29 10:45:26 -0400 (Wed, 29 Oct 2008)
New Revision: 10966
Modified:
trunk/sandbox/samples/editorSeam-sample/src/main/webapp/WEB-INF/web.xml
Log:
Remove tiny mce resources loader servlet from web.xml
Modified: trunk/sandbox/samples/editorSeam-sample/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/sandbox/samples/editorSeam-sample/src/main/webapp/WEB-INF/web.xml 2008-10-29 14:40:30 UTC (rev 10965)
+++ trunk/sandbox/samples/editorSeam-sample/src/main/webapp/WEB-INF/web.xml 2008-10-29 14:45:26 UTC (rev 10966)
@@ -20,10 +20,7 @@
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
- <servlet-name>Faces Servlet</servlet-name>
- <dispatcher>FORWARD</dispatcher>
- <dispatcher>REQUEST</dispatcher>
- <dispatcher>INCLUDE</dispatcher>
+ <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
@@ -34,15 +31,6 @@
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
- <!-- servlet>
- <display-name>TinyMCE Loader Servlet</display-name>
- <servlet-name>TinyMCELoaderServlet</servlet-name>
- <servlet-class>org.richfaces.component.TinyMceLoaderServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>TinyMCELoaderServlet</servlet-name>
- <url-pattern>/a4j/g/3_3_0-SNAPSHOTorg/richfaces/renderkit/html/scripts/tiny_mce/*</url-pattern>
- </servlet-mapping-->
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
16 years, 2 months