001    /*
002     * Jpkg - Java library and tools for operating system package creation.
003     *
004     * Copyright (c) 2007 Three Rings Design, Inc.
005     * All rights reserved.
006     *
007     * Redistribution and use in source and binary forms, with or without
008     * modification, are permitted provided that the following conditions
009     * are met:
010     * 1. Redistributions of source code must retain the above copyright
011     *    notice, this list of conditions and the following disclaimer.
012     * 2. Redistributions in binary form must reproduce the above copyright
013     *    notice, this list of conditions and the following disclaimer in the
014     *    documentation and/or other materials provided with the distribution.
015     * 3. Neither the name of the copyright owner nor the names of contributors
016     *    may be used to endorse or promote products derived from this software
017     *    without specific prior written permission.
018     *
019     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
023     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
024     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
025     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
026     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
027     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
029     * POSSIBILITY OF SUCH DAMAGE.
030     */
031    package com.threerings.jpkg.ant.dpkg.info;
032    
033    import java.util.ArrayList;
034    import java.util.List;
035    
036    import com.threerings.antidote.ValidStatus;
037    import com.threerings.antidote.field.FieldWrapper;
038    import com.threerings.antidote.field.OptionalField;
039    import com.threerings.antidote.field.RequiredField;
040    import com.threerings.antidote.field.text.TextField;
041    import com.threerings.antidote.field.text.TextStatus;
042    import com.threerings.jpkg.ant.dpkg.info.description.Blank;
043    import com.threerings.jpkg.ant.dpkg.info.description.DescriptionAction;
044    import com.threerings.jpkg.ant.dpkg.info.description.Paragraph;
045    import com.threerings.jpkg.ant.dpkg.info.description.Summary;
046    import com.threerings.jpkg.ant.dpkg.info.description.Verbatim;
047    import com.threerings.jpkg.debian.ControlDataInvalidException;
048    import com.threerings.jpkg.debian.PackageDescription;
049    
050    import static com.threerings.antidote.MutabilityHelper.areMutablesSet;
051    import static com.threerings.antidote.MutabilityHelper.requiresValidation;
052    
053    
054    /**
055     * Stores the <info> <description> field, which is the package description.
056     * @see PackageDescription
057     */
058    public class Description extends TextField
059    {
060        // from Field
061        public String getFieldName ()
062        {
063            return "description";
064        }
065    
066        /**
067         * Ant adder field: Add the summary description.
068         */
069        public void addSummary (Summary summary)
070        {
071            _summary.setField(summary);
072        }
073    
074        /**
075         * Ant adder field: Add a blank line to this description.
076         */
077        public void addBlank (Blank blank)
078        {
079            _actions.add(new RequiredField<Blank>(blank, this));
080        }
081    
082        /**
083         * Ant adder field: Add a word wrapped paragraph to this description.
084         */
085        public void addParagraph (Paragraph paragraph)
086        {
087            _actions.add(new RequiredField<Paragraph>(paragraph, this));
088        }
089    
090        /**
091         * Ant adder field: Add a none word wrapped verbatim paragraph to this description.
092         */
093        public void addVerbatim (Verbatim verbatim)
094        {
095            _actions.add(new RequiredField<Verbatim>(verbatim, this));
096        }
097    
098        /**
099         * Returns the user data converted into a {@link PackageDescription}. Cannot be called before validate().
100         */
101        public PackageDescription getPackageDescription ()
102        {
103            requiresValidation(_packageDescription);
104            return _packageDescription;
105        }
106    
107        @Override // from BaseComponent
108        protected void validateField ()
109        {
110            String summaryText = null;
111            // either the description has the summary provided in a <summary> field with optional
112            // additional fields or it is provided in a simpler <description>summary</description>
113            switch (areMutablesSet(_summary)) {
114                case ALL_UNSET:
115                case SOME_UNSET:
116                    // if other actions were declared, but no <summary> was set, report the missing field.
117                    if (_actions.size() > 0) {
118                        reportUnsetField(_summary);
119                        return;
120                    }
121    
122                    // otherwise the simple <description>description</description> form must have been
123                    // used so pull the summary text from the text field.
124                    if (validateTextNotEmpty() == TextStatus.INVALID_TEXT) return;
125                    scrubTextWhitespace();
126    
127                    summaryText = getText();
128                    break;
129    
130                case ALL_SET:
131                    // the <summary> field was set so validate it and pull the summary text from there.
132                    if (validateChildFields(_summary) == ValidStatus.ALL_INVALID) return;
133    
134                    summaryText = _summary.getField().getSummary();
135                    break;
136            }
137    
138            // create the PackageDescription with the summary text
139            try {
140                _packageDescription = new PackageDescription(summaryText);
141    
142            } catch (final ControlDataInvalidException cdie) {
143                appendViolation(new ControlDataViolation(this, cdie));
144                return;
145            }
146    
147            // if we have no additional actions to perform on the description, return.
148            if (_actions.size() == 0) {
149                return;
150            }
151    
152            // validate each action field,
153            switch (validateChildFields(_actions)) {
154                case ALL_INVALID:
155                case SOME_INVALID:
156                    return;
157    
158                case ALL_VALID:
159                    break;
160            }
161    
162            // apply each action field to the description.
163            for (final FieldWrapper<? extends DescriptionAction> field : _actions) {
164                appendViolationList(field.getField().apply(_packageDescription));
165            }
166        }
167    
168        /** The list of {@link DescriptionAction} objects to apply to this description. */
169        private final List<RequiredField<? extends DescriptionAction>> _actions =
170            new ArrayList<RequiredField<? extends DescriptionAction>>();
171    
172        /** Ant adder/setter fields. */
173        private final OptionalField<Summary> _summary = new OptionalField<Summary>(Summary.class, this);
174    
175        /** The PackageDescription object representing the user supplied data. */
176        private PackageDescription _packageDescription;
177    }