001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors. 
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.graph.commands.basic;
023    
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Collections;
027    import java.util.Iterator;
028    import java.util.List;
029    import java.util.Map;
030    import net.jcip.annotations.NotThreadSafe;
031    import org.jboss.dna.graph.commands.GraphCommand;
032    import org.jboss.dna.graph.properties.Name;
033    import org.jboss.dna.graph.properties.Path.Segment;
034    import org.jboss.dna.graph.properties.basic.BasicPathSegment;
035    
036    /**
037     * @author Randall Hauch
038     */
039    @NotThreadSafe
040    public abstract class BasicGraphCommand implements GraphCommand {
041    
042        private boolean cancelled = false;
043        private Throwable error;
044    
045        /**
046         * 
047         */
048        public BasicGraphCommand() {
049        }
050    
051        /**
052         * {@inheritDoc}
053         */
054        public boolean isCancelled() {
055            return cancelled;
056        }
057    
058        /**
059         * @param cancelled Sets cancelled to the specified value.
060         */
061        public void setCancelled( boolean cancelled ) {
062            this.cancelled = cancelled;
063        }
064    
065        /**
066         * {@inheritDoc}
067         * 
068         * @see org.jboss.dna.graph.commands.GraphCommand#setError(java.lang.Throwable)
069         */
070        public void setError( Throwable t ) {
071            error = t;
072        }
073    
074        /**
075         * {@inheritDoc}
076         * 
077         * @see org.jboss.dna.graph.commands.GraphCommand#getError()
078         */
079        public Throwable getError() {
080            return error;
081        }
082    
083        /**
084         * {@inheritDoc}
085         * 
086         * @see org.jboss.dna.graph.commands.GraphCommand#hasError()
087         */
088        public boolean hasError() {
089            return error != null;
090        }
091    
092        public boolean hasNoError() {
093            return error == null;
094        }
095    
096        // ----------------------------------------------------------------------------------------------------------------
097        // Utility methods used by concrete command implementations
098        // ----------------------------------------------------------------------------------------------------------------
099    
100        protected List<Segment> createChildrenList( Name nameOfChild ) {
101            if (nameOfChild == null) {
102                return Collections.emptyList();
103            }
104            return Collections.singletonList((Segment)new BasicPathSegment(nameOfChild));
105        }
106    
107        protected List<Segment> createChildrenList( Iterator<Segment> namesOfChildren ) {
108            if (namesOfChildren == null) {
109                return Collections.emptyList();
110            }
111            List<Segment> children = new ArrayList<Segment>();
112            while (namesOfChildren.hasNext()) {
113                children.add(namesOfChildren.next());
114            }
115            return children;
116        }
117    
118        protected List<Segment> createChildrenList( Iterable<Segment> namesOfChildren ) {
119            if (namesOfChildren == null) {
120                return Collections.emptyList();
121            }
122            List<Segment> children = new ArrayList<Segment>();
123            for (Segment childSegment : namesOfChildren) {
124                children.add(childSegment);
125            }
126            return children;
127        }
128    
129        protected static List<Segment> createChildrenList( Segment... namesOfChildren ) {
130            if (namesOfChildren == null || namesOfChildren.length == 0) {
131                return Collections.emptyList();
132            }
133            List<Segment> children = new ArrayList<Segment>();
134            for (Segment childSegment : namesOfChildren) {
135                children.add(childSegment);
136            }
137            return children;
138        }
139    
140        protected static void setProperty( Map<Name, List<Object>> propertyValues,
141                                           Name propertyName,
142                                           Object... values ) {
143            if (values == null || values.length == 0) {
144                propertyValues.remove(propertyName);
145            } else {
146                List<Object> valuesList = null;
147                if (values.length == 1) {
148                    Object value = values[0];
149                    if (value instanceof Collection<?>) {
150                        setProperty(propertyValues, propertyName, ((Collection<?>)value).iterator());
151                        return;
152                    } else if (value instanceof Iterable<?>) {
153                        setProperty(propertyValues, propertyName, (Iterable<?>)value);
154                        return;
155                    } else if (value instanceof Iterator<?>) {
156                        setProperty(propertyValues, propertyName, (Iterator<?>)value);
157                        return;
158                    }
159                    // Otherwise, single object is just a normal value ...
160                    valuesList = Collections.singletonList(value);
161                } else {
162                    assert values.length > 1;
163                    valuesList = new ArrayList<Object>(values.length);
164                    for (Object arrayValue : values) {
165                        valuesList.add(arrayValue);
166                    }
167                }
168                propertyValues.put(propertyName, valuesList);
169            }
170        }
171    
172        protected static void setProperty( Map<Name, List<Object>> propertyValues,
173                                           Name propertyName,
174                                           Iterable<?> values ) {
175            if (values == null) {
176                propertyValues.remove(propertyName);
177            } else {
178                List<Object> valuesList = new ArrayList<Object>();
179                for (Object value : values) {
180                    valuesList.add(value);
181                }
182                propertyValues.put(propertyName, valuesList);
183            }
184        }
185    
186        protected static void setProperty( Map<Name, List<Object>> propertyValues,
187                                           Name propertyName,
188                                           Iterator<?> values ) {
189            if (values == null) {
190                propertyValues.remove(propertyName);
191            } else {
192                List<Object> valuesList = new ArrayList<Object>();
193                while (values.hasNext()) {
194                    Object value = values.next();
195                    valuesList.add(value);
196                }
197                propertyValues.put(propertyName, valuesList);
198            }
199        }
200    
201    }