Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package de.zalando.typemapper.postgres;
  
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
 
 
 
 public class HStore extends PGobject implements Iterable<Entry<StringString>> {
 
     private static final long serialVersionUID = -2491617655490561600L;
 
     private int length;
 
     public HStore(final String rawValue) {
         this. = "hstore";
         this. = rawValue;
         this. = rawValue == null ? 0 : rawValue.length();
     }
 
     public HStore() {
         this. = "hstore";
         this. = 0;
     }
 
     public HStore(final Map<?, ?> map) {
         this((new HStoreSerializer(map)).toPgString(null));
     }
 
     @Override
     public void setValue(final String rawValue) {
         if (!"hstore".equals(this.)) {
             throw new IllegalStateException("HStore database type name should be 'hstore'");
         }
 
         this. = rawValue;
         this. = rawValue == null ? 0 : rawValue.length();
     }
 
     public Map<StringStringasMap() {
         HashMap<StringStringr = new HashMap<StringString>();
         try {
             for (final HStoreIterator iterator = new HStoreIterator(); iterator.hasNext();) {
                 final HStoreEntry entry = iterator.rawNext();
                 r.put(entry.keyentry.value);
             }
         } catch (HStoreParseException e) {
             throw new IllegalStateException(e);
         }
 
         return r;
     }
 
     public static String serialize(final Map<?, ?> map) {
         return (new HStoreSerializer(map)).toPgString(null);
     }
 
     private static final class HStoreSerializer extends AbstractPgSerializer {
 
         private final Map<ObjectObjectmap;
 
         @SuppressWarnings("unchecked")
         protected HStoreSerializer(final Map<?, ?> map) {
             this. = (Map<ObjectObject>) map;
         }
 
         @Override
         public boolean isNull() {
             return  == null;
         }
 
         @Override
         protected boolean isEmpty() {
             return .isEmpty();
         }
 
         @Override
         protected String getEmpty() {
             return "\"\"";
         }
 
         @Override
         protected void appendNull(final StringBuilder sb) {
             sb.append();
         }
 
         @Override
         public StringBuilder quote(final StringBuilder sbfinal CharSequence s) {
             if (sb == null) {
                 throw new NullPointerException("Passed StringBuilder should be not null");
             }
 
             if (s == null) {
                throw new NullPointerException("Null values should be processed by the caller");
            }
            final int l = s.length();
            if (l == 0) {
                return sb.append("\"\"");
            }
            // find if there are quotes or commas in the string
            int neededLength = 0;
            for (int i = 0; i < li++) {
                final char ch = s.charAt(i);
                neededLength++;
                if (ch ==  || ch == ) {
                    neededLength++;
                }
            }
            sb.ensureCapacity(sb.length() + neededLength + 2);
            // start quotation
            sb.append();
            for (int i = 0; i < li++) {
                final char ch = s.charAt(i);
                if (ch ==  || ch == ) {
                    sb.append().append(ch);
                } else {
                    sb.append(ch);
                }
            }
            sb.append();
            return sb;
        }
        @Override
        public String toPgString(final Connection connection) {
            final Iterator<Entry<ObjectObject>> iterator = .entrySet().iterator();
            StringBuilder sb = new StringBuilder();
            boolean hasNext = iterator.hasNext();
            while (hasNext) {
                Entry<ObjectObjectentry = iterator.next();
                assert entry != null;
                final Object key = entry.getKey();
                if (key == null) {
                    throw new IllegalArgumentException("Null keys are not supported by HStore");
                } else {
                    quote(sb, PgTypeHelper.toPgString(key));
                }
                sb.append("=>");
                final Object value = entry.getValue();
                if (value == null) {
                    sb.append();
                } else {
                    quote(sb, PgTypeHelper.toPgString(value));
                }
                hasNext = iterator.hasNext();
                if (hasNext) {
                    sb.append(',');
                } else {
                    break;
                }
            }
            return sb.toString();
        }
    }
    private static class HStoreEntry implements Entry<StringString> {
        private String key;
        private String value;
        HStoreEntry(final String keyfinal String value) {
            this. = key;
            this. = value;
        }
        @Override
        public String getKey() {
            return ;
        }
        @Override
        public String getValue() {
            return ;
        }
        @Override
        public String setValue(final String value) {
            final String oldValue = this.;
            this. = value;
            return oldValue;
        }
    }
    private static enum ParseState {
        WaitingForKey,
        WaitingForEquals,
        WaitingForGreater,
        WaitingForValue,
        WaitingForComma
    }
    private static final char QUOTE = '"';
    private static final char BACKSLASH = '\\';
    private static final char EQUALS = '=';
    private static final char GREATER = '>';
    private static final char COMMA = ',';
    private static final String NULL = "NULL";
    private class HStoreIterator implements Iterator<Entry<StringString>> {
        private int position;
        private HStoreEntry lastReturned;
        private HStoreEntry nextEntry;
        public HStoreIterator() throws HStoreParseException {
            this. = -1;
            advance();
        }
        @Override
        public boolean hasNext() {
            return  != null;
        }
        private HStoreEntry rawNext() throws NoSuchElementExceptionHStoreParseException {
            if ( == null) {
                throw new NoSuchElementException();
            }
             = ;
            advance();
            return ;
        }
        @Override
        public Entry<StringStringnext() throws NoSuchElementExceptionIllegalStateException {
            try {
                return rawNext();
            } catch (HStoreParseException e) {
                throw new IllegalStateException(e);
            }
        }

        
Advance in parsing the rawValue string and assign the nextValue It creates a new nextElement or assigns null to it, if there are no more elements.

        private void advance() throws HStoreParseException {
            String elementKey = null;
            String elementValue = null;
            ParseState state = .;
            loop:
            while ( <  - 1) {
                final char ch = .charAt(++);
                switch (state) {
                    case  :
                        if (Character.isWhitespace(ch)) {
                            continue;
                        }
                        if (ch == ) {
                            elementKey = advanceQuoted();
                        } else {
                            // we have non-quote char, so start loading the key
                            elementKey = advanceWord();
                            // hstore does not support NULL keys, so NULLs are loaded as usual strings
                        }
                        state = .;
                        continue;
                    case  :
                        if (Character.isWhitespace(ch)) {
                            continue;
                        }
                        if (ch == ) {
                            state = .;
                            continue;
                        } else {
                            throw new HStoreParseException("Expected '=>' key-value separator");
                        }
                    case  :
                        if (ch == ) {
                            state = .;
                            continue;
                        } else {
                            throw new HStoreParseException("Expected '=>' key-value separator");
                        }
                    case  :
                        if (Character.isWhitespace(ch)) {
                            continue;
                        }
                        if (ch == ) {
                            elementValue = advanceQuoted();
                        } else {
                            // we have non-quote char, so start loading the key
                            elementValue = advanceWord();
                            // hstore supports NULL values, so if unquoted NULL is there, it is rewritten to null
                            if (.equalsIgnoreCase(elementValue)) {
                                elementValue = null;
                            }
                        }
                        state = .;
                        continue;
                    case  :
                        if (Character.isWhitespace(ch)) {
                            continue;
                        }
                        if (ch == ) {
                            // we are done
                            break loop;
                        } else {
                            throw new HStoreParseException("Cannot find comma as an end of the value: '" +  + "'",
                                );
                        }
                    default :
                        throw new IllegalStateException("Unknown HStoreParser state");
                }
            } // loop
            // here we either consumed whole string or we found a comma
            if (state == .) {
                // string was consumed when waiting for key, so we are done with processing
                 = null;
                return;
            }
            if (state != .) {
                throw new HStoreParseException("Unexpected end of string");
            }
            if (elementKey == null) {
                throw new HStoreParseException("Internal parsing error");
            }
            // init nextValue
             = new HStoreEntry(elementKeyelementValue);
        }
        private String advanceQuoted() throws HStoreParseException {
            final int firstQuotePosition = ;
            StringBuilder sb = null;
            boolean insideQuote = true;
            while ( <  - 1) {
                char ch = .charAt(++);
                if (ch == ) {
                    // we saw a backslash, it is either a escaped quote or escaped backslash
                    final int nextPosition =  + 1;
                    if (nextPosition < ) {
                        final char nextCh = .charAt(nextPosition);
                        if (nextCh == ) {
                            // it was a escaped quote, so we have to push a quote into the result
                            if (sb == null) {
                                sb = new StringBuilder(.substring(firstQuotePosition + 1, ));
                            }
                            sb.append();
                            ++;
                            continue;
                        } else if (nextCh == ) {
                            // it was a escaped backslash, so we have to push a "\" into the result
                            if (sb == null) {
                                sb = new StringBuilder(.substring(firstQuotePosition + 1, ));
                            }
                            sb.append();
                            ++;
                            continue;
                        }
                    }
                    throw new HStoreParseException("Backslash without following backslash or quote at position "
                            + );
                } else if (ch == ) {
                    // it was a closing quote as we either ware are at the end of the rawValue string
                    // or we could not find the next quote
                    insideQuote = false;
                    break;
                } else {
                    if (sb != null) {
                        sb.append(ch);
                    }
                }
            }
            if (insideQuote) {
                throw new HStoreParseException("Quote at string position " + firstQuotePosition + " is not closed",
                    );
            }
            if (sb == null) {
                // we consumed the last quote
                String r = .substring(firstQuotePosition + 1, );
                return r;
            } else {
                return sb.toString();
            }
        }
        private String advanceWord(final char stopAtCharthrows HStoreParseException {
            final int firstWordPosition = ;
            while ( < ) {
                final char ch = .charAt();
                if (ch == ) {
                    throw new HStoreParseException("Unexpected quote in word");
                } else if (Character.isWhitespace(ch) || ch == stopAtChar) {
                    break;
                }
                ++;
            }
            // step back as we are already one char away
            --;
            // substring is using quite a strange way of defining end position
            final String r = .substring(firstWordPosition + 1);
            return r;
        }
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    @Override
    public Iterator<Entry<StringString>> iterator() {
        try {
            return new HStoreIterator();
        } catch (HStoreParseException e) {
            throw new IllegalStateException(e);
        }
    }
New to GrepCode? Check out our FAQ X