001    // Protocol Buffers - Google's data interchange format
002    // Copyright 2008 Google Inc.
003    // http://code.google.com/p/protobuf/
004    //
005    // Licensed under the Apache License, Version 2.0 (the "License");
006    // you may not use this file except in compliance with the License.
007    // You may obtain a copy of the License at
008    //
009    //      http://www.apache.org/licenses/LICENSE-2.0
010    //
011    // Unless required by applicable law or agreed to in writing, software
012    // distributed under the License is distributed on an "AS IS" BASIS,
013    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014    // See the License for the specific language governing permissions and
015    // limitations under the License.
016    
017    package org.fusesource.hawtbuf.proto;
018    
019    import java.util.Collections;
020    import java.util.List;
021    
022    /**
023     * Thrown when attempting to build a protocol message that is missing required
024     * fields. This is a {@code RuntimeException} because it normally represents a
025     * programming error: it happens when some code which constructs a message fails
026     * to set all the fields. {@code parseFrom()} methods <b>do not</b> throw this;
027     * they throw an {@link InvalidProtocolBufferException} if required fields are
028     * missing, because it is not a programming error to receive an incomplete
029     * message. In other words, {@code UninitializedMessageException} should never
030     * be thrown by correct code, but {@code InvalidProtocolBufferException} might
031     * be.
032     * 
033     * @author kenton@google.com Kenton Varda
034     */
035    public class UninitializedMessageException extends RuntimeException {
036    
037        public UninitializedMessageException(List<String> missingFields) {
038            super(buildDescription(missingFields));
039            this.missingFields = missingFields;
040        }
041    
042        private final List<String> missingFields;
043    
044        /**
045         * Get a list of human-readable names of required fields missing from this
046         * message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
047         */
048        public List<String> getMissingFields() {
049            return Collections.unmodifiableList(missingFields);
050        }
051    
052        /**
053         * Converts this exception to an {@link InvalidProtocolBufferException}.
054         * When a parsed message is missing required fields, this should be thrown
055         * instead of {@code UninitializedMessageException}.
056         */
057        public InvalidProtocolBufferException asInvalidProtocolBufferException() {
058            return new InvalidProtocolBufferException(getMessage());
059        }
060    
061        /** Construct the description string for this exception. */
062        private static String buildDescription(List<String> missingFields) {
063            StringBuilder description = new StringBuilder("Message missing required fields: ");
064            boolean first = true;
065            for (String field : missingFields) {
066                if (first) {
067                    first = false;
068                } else {
069                    description.append(", ");
070                }
071                description.append(field);
072            }
073            return description.toString();
074        }
075    
076    }