View Javadoc

1   /**
2    * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    * * Redistributions of source code must retain the above copyright
8    * notice, this list of conditions and the following disclaimer.
9    * * Redistributions in binary form must reproduce the above copyright
10   * notice, this list of conditions and the following disclaimer in the
11   * documentation and/or other materials provided with the distribution.
12   * * Neither the name of the University of Konstanz nor the
13   * names of its contributors may be used to endorse or promote products
14   * derived from this software without specific prior written permission.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  
28  package org.treetank.bucket;
29  
30  import static com.google.common.base.Objects.toStringHelper;
31  
32  import java.io.DataInput;
33  import java.io.IOException;
34  
35  import org.treetank.api.IMetaEntry;
36  import org.treetank.api.IMetaEntryFactory;
37  import org.treetank.api.IDataFactory;
38  import org.treetank.bucket.DataBucket.DeletedData;
39  import org.treetank.bucket.interfaces.IBucket;
40  import org.treetank.bucket.interfaces.IReferenceBucket;
41  import org.treetank.exception.TTIOException;
42  
43  import com.google.inject.Inject;
44  import com.google.inject.Singleton;
45  
46  /**
47   * Factory to deserialize buckets out of a chunk of bytes.
48   * This factory needs a {@link IDataFactory}-reference to perform inlying data-serializations as well.
49   * 
50   * @author Sebastian Graf, University of Konstanz
51   * 
52   */
53  @Singleton
54  public final class BucketFactory {
55  
56      /** Data Factory to be initialized. */
57      private final IDataFactory mDataFac;
58  
59      /** MetaEntry Factory to be initialized. */
60      private final IMetaEntryFactory mEntryFac;
61  
62      /**
63       * Constructor.
64       * 
65       * @param pDataFac
66       *            to be set
67       */
68      @Inject
69      public BucketFactory(final IDataFactory pDataFac, final IMetaEntryFactory pMetaFac) {
70          mDataFac = pDataFac;
71          mEntryFac = pMetaFac;
72      }
73  
74      /**
75       * Create bucket.
76       * 
77       * @param pInput
78       *            source to read from
79       * @return the created bucket
80       * @throws TTIOException
81       */
82      public IBucket deserializeBucket(final DataInput pInput) throws TTIOException {
83          try {
84              final int kind = pInput.readInt();
85              byte[] hash;
86              switch (kind) {
87              case IConstants.DATABUCKET:
88                  DataBucket dataBucket = new DataBucket(pInput.readLong(), pInput.readLong());
89                  for (int offset = 0; offset < IConstants.CONTENT_COUNT; offset++) {
90                      int dataKind = pInput.readInt();
91                      if (dataKind != IConstants.NULLDATA) {
92                          if (dataKind == IConstants.DELETEDDATA) {
93                              dataBucket.getDatas()[offset] = new DeletedData(pInput.readLong());
94                          } else {
95                              dataBucket.getDatas()[offset] = mDataFac.deserializeData(pInput);
96                          }
97                      }
98                  }
99                  return dataBucket;
100             case IConstants.METABUCKET:
101                 MetaBucket metaBucket = new MetaBucket(pInput.readLong());
102                 final int mapSize = pInput.readInt();
103                 IMetaEntry key;
104                 IMetaEntry value;
105                 for (int i = 0; i < mapSize; i++) {
106                     key = mEntryFac.deserializeEntry(pInput);
107                     value = mEntryFac.deserializeEntry(pInput);
108                     metaBucket.put(key, value);
109                 }
110                 return metaBucket;
111             case IConstants.UBERBUCKET:
112                 UberBucket uberBucket =
113                     new UberBucket(pInput.readLong(), pInput.readLong(), pInput.readLong());
114                 uberBucket.setReferenceKey(0, pInput.readLong());
115                 hash = new byte[pInput.readInt()];
116                 pInput.readFully(hash);
117                 uberBucket.setReferenceHash(IReferenceBucket.GUARANTEED_INDIRECT_OFFSET, hash);
118                 return uberBucket;
119             case IConstants.INDIRCTBUCKET:
120                 IndirectBucket indirectBucket = new IndirectBucket(pInput.readLong());
121                 for (int offset = 0; offset < indirectBucket.getReferenceKeys().length; offset++) {
122                     indirectBucket.setReferenceKey(offset, pInput.readLong());
123                 }
124                 for (int offset = 0; offset < indirectBucket.getReferenceHashs().length; offset++) {
125                     hash = new byte[pInput.readInt()];
126                     pInput.readFully(hash);
127                     indirectBucket.setReferenceHash(offset, hash);
128                 }
129                 return indirectBucket;
130             case IConstants.REVISIONROOTBUCKET:
131                 RevisionRootBucket revRootBucket =
132                     new RevisionRootBucket(pInput.readLong(), pInput.readLong(), pInput.readLong());
133                 for (int offset = 0; offset < revRootBucket.getReferenceKeys().length; offset++) {
134                     revRootBucket.setReferenceKey(offset, pInput.readLong());
135                 }
136                 for (int offset = 0; offset < revRootBucket.getReferenceHashs().length; offset++) {
137                     hash = new byte[pInput.readInt()];
138                     pInput.readFully(hash);
139                     revRootBucket.setReferenceHash(offset, hash);
140                 }
141                 return revRootBucket;
142             default:
143                 throw new IllegalStateException(
144                     "Invalid Kind of Bucket. Something went wrong in the serialization/deserialization");
145             }
146         } catch (final IOException exc) {
147             throw new TTIOException(exc);
148         }
149     }
150 
151     /**
152      * {@inheritDoc}
153      */
154     @Override
155     public String toString() {
156         return toStringHelper(this).add("mDataFac", mDataFac).add("mEntryFac", mEntryFac).toString();
157     }
158 
159 }