PageRenderTime 212ms CodeModel.GetById 200ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/SplitConfigParser.java

#
Java | 337 lines | 241 code | 30 blank | 66 comment | 27 complexity | 67548d10838b01e616506306dabe7ec5 MD5 | raw file
  1/*
  2 * :tabSize=8:indentSize=8:noTabs=false:
  3 * :folding=explicit:collapseFolds=1:
  4 *
  5 * Copyright (C) 1999, 2004 Slava Pestov
  6 *
  7 * This program is free software; you can redistribute it and/or
  8 * modify it under the terms of the GNU General Public License
  9 * as published by the Free Software Foundation; either version 2
 10 * of the License, or any later version.
 11 *
 12 * This program is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 * GNU General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU General Public License
 18 * along with this program; if not, write to the Free Software
 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 20 */
 21 
 22package org.gjt.sp.jedit;
 23
 24import java.io.IOException;
 25import java.io.StreamTokenizer;
 26import java.io.StringReader;
 27import java.util.ArrayDeque;
 28import java.util.ArrayList;
 29import java.util.Deque;
 30import java.util.List;
 31
 32public class SplitConfigParser 
 33{
 34
 35	//{{{ private members
 36        private String splitConfig;
 37
 38        private boolean includeSplits = true;
 39        private boolean includeFiles = true;
 40        private boolean includeRemotes = false;
 41        //}}}
 42        
 43        //{{{ SplitConfigParser constructor
 44	/**
 45	 * @param splitConfig The string to parse and adjust.
 46	 */
 47        public SplitConfigParser(String splitConfig) 
 48        {
 49                this.splitConfig = splitConfig == null ? "" : splitConfig;
 50        }
 51        //}}}
 52
 53        //{{{ Setters
 54	/**
 55	 * @param b If true, retain any splits in the split configuration.
 56	 */
 57        public void setIncludeSplits(boolean b) 
 58        {
 59                includeSplits = b;
 60        }
 61
 62	/**
 63	 * @param b If true, retain any file names found in the split configuration.
 64	 */
 65        public void setIncludeFiles(boolean b) 
 66        {
 67                includeFiles = b;
 68        }
 69
 70	/**
 71	 * @param b If true, and if include files is true, then retain any remote file
 72	 * names found in the split configuration.
 73	 */
 74        public void setIncludeRemoteFiles(boolean b) 
 75        {
 76                includeRemotes = includeFiles && b;
 77        }
 78        //}}}
 79
 80        //{{{ parse()
 81	/**
 82	 * Parses the given split configuration string and removes splits, file names,
 83	 * and remote file names bases on the settings for this parser.
 84	 * @return The split configuration string adjusted for user preferences.
 85	 */
 86        public String parse() 
 87        {
 88                if (splitConfig == null || splitConfig.length() == 0) 
 89                {
 90                        return "";
 91                }
 92
 93                Deque<Object> tokenStack = new ArrayDeque<Object>();
 94                Deque<Object> splitStack = new ArrayDeque<Object>();
 95
 96                BufferSet bufferset = new BufferSet(includeFiles, includeRemotes);
 97                boolean haveSplit = false;
 98
 99                try 
100                {
101                        StreamTokenizer st = new StreamTokenizer(new StringReader(splitConfig));
102                        st.whitespaceChars(0, ' ');
103                        st.wordChars('#', '~');
104                        st.commentChar('!');
105                        st.quoteChar('"');
106                        st.eolIsSignificant(false);
107
108                        int token = st.nextToken();
109
110                        while (token != StreamTokenizer.TT_EOF) 
111                        {
112                                switch (token) 
113                                {
114                                        case StreamTokenizer.TT_WORD:
115                                                if ("vertical".equals(st.sval) || "horizontal".equals(st.sval)) 
116                                                {
117							// handle split -- create new Split, populate it with
118							// the first 2 items in the split stack.
119                                                        if (includeSplits) 
120                                                        {
121                                                                Object right = splitStack.pop();
122                                                                Object left = splitStack.pop();
123                                                                Split split = new Split();
124                                                                split.setLeft(left);
125                                                                split.setRight(right);
126                                                                split.setDirection(st.sval);
127                                                                int offset = (Integer) tokenStack.pop();
128                                                                split.setOffset(offset);
129                                                                splitStack.push(split);
130                                                                haveSplit = true;
131                                                        }
132                                                } 
133                                                else if ("buffer".equals(st.sval) || "buff".equals(st.sval)) 
134                                                {
135							// add to buffer set
136                                                        Object filename = tokenStack.pop();
137                                                        bufferset.addBuffer(filename.toString());
138                                                } 
139                                                else if ("bufferset".equals(st.sval)) 
140                                                {
141							// close out current buffer set, push to split stack,
142							// create new buffer set.
143                                                        Object scope = tokenStack.pop();
144                                                        bufferset.setScope(scope.toString());
145                                                        splitStack.push(bufferset);
146                                                        bufferset = new BufferSet(includeFiles, includeRemotes);
147                                                }
148                                                break;
149                                        case StreamTokenizer.TT_NUMBER:
150                                                tokenStack.push((int) st.nval);
151                                                break;
152                                        case '"':
153                                                tokenStack.push(st.sval);
154                                                break;
155                                }
156                                token = st.nextToken();
157                        }
158                        StringBuilder sb = new StringBuilder();
159			// check if splitStack has any Split objects, if not, collapse all
160			// BufferSets to a single BufferSet.
161                        if (haveSplit) 
162                        {
163                                while (!splitStack.isEmpty()) 
164                                {
165                                        sb.append(splitStack.pop().toString()).append(' ');
166                                }
167                        } 
168                        else 
169                        {
170                        	// no splits, only buffersets
171                                BufferSet allBuffers = new BufferSet();
172                                while (!splitStack.isEmpty()) 
173                                {
174                                        BufferSet bs = (BufferSet) splitStack.pop();
175                                        if (allBuffers.getScope() == null) 
176                                        {
177                                                allBuffers.setScope(bs.getScope());
178                                        }
179                                        allBuffers.addBufferSet(bs);
180                                }
181                                sb.append(allBuffers.toString());
182                        }
183                        // need the replaceAll to make sure Windows backslashes
184                        // don't get unescaped prematurely
185                        return sb.toString().replaceAll("\\\\", "\\\\\\\\").trim();
186                } 
187                catch (IOException e) 
188                {
189			// StringReader will not throw an IOException as long as the
190			// string it is reading is not null, which won't happen here.
191                }
192                return splitConfig;
193        }
194        //}}}
195
196        //{{{ BufferSet
197        // Represents a set of file names for buffers.
198        private class BufferSet 
199        {
200                List<String> buffers = new ArrayList<String>();
201                String scope = null;
202
203                boolean includeFiles = true;
204                boolean includeRemotes = false;
205
206                public BufferSet() {}
207
208                public BufferSet(boolean includeFiles, boolean includeRemotes) 
209                {
210                        this.includeFiles = includeFiles;
211                        this.includeRemotes = includeRemotes;
212                }
213
214                public void addBuffer(String s) 
215                {
216                        if (includeFiles) 
217                        {
218                        	if (includeRemotes) 
219                        	{
220                        		buffers.add(s);
221                        		return;
222                        	}
223                                if (!isRemote(s)) 
224                                {
225                                        buffers.add(s);
226                                }
227                        }
228                }
229
230                public List<String> getBuffers() 
231                {
232                        return buffers;
233                }
234
235                public void addBufferSet(BufferSet bs) 
236                {
237                        buffers.addAll(bs.getBuffers());
238                }
239
240                public void setScope(String s) 
241                {
242                        scope = s;
243                }
244
245                public String getScope() 
246                {
247                        return scope;
248                }
249
250                public String toString() 
251                {
252                        StringBuilder sb = new StringBuilder();
253                        if (buffers.size() == 0) 
254                        {
255                                sb.append("\"Untitled-1\" buffer ");
256                        } 
257                        else 
258                        {
259                                for (int i = 0; i < buffers.size(); i++) 
260                                {
261                                        sb.append('\"').append(buffers.get(i)).append('\"');
262                                        sb.append(i == 0 ? " buffer " : " buff ");
263                                }
264                        }
265                        if (scope == null) 
266                        {
267                        	scope = "view";
268                        } 
269                        sb.append('\"').append(scope).append("\" bufferset");
270                        return sb.toString();
271                }
272
273                /**
274                 * @return true if the uri points to a file that is remote, that is, the
275                 * protocol of the give uri is something other than 'file'.
276                 */
277                public boolean isRemote(String uri) 
278                {
279                        if (MiscUtilities.isURL(uri)) 
280                        {
281                                String protocol = MiscUtilities.getProtocolOfURL(uri);
282                                return !protocol.equals("file");
283                        }
284                        return false;
285                }
286        }
287        //}}}
288
289        //{{{ Split
290        private class Split 
291        {
292                Object left = null;
293                Object right = null;
294                String direction = null;
295                int offset = 0;
296
297                // no error checking, assumes caller will pass a BufferSet or a Split
298                public void setLeft(Object left) 
299                {
300                        this.left = left;
301                }
302
303                // no error checking, assumes caller will pass a BufferSet or a Split
304                public void setRight(Object right) 
305                {
306                        this.right = right;
307                }
308
309                // no error checking, assumes caller will send 'horizontal' or 'vertical'
310                public void setDirection(String direction) 
311                {
312                        this.direction = direction;
313                }
314
315                // no error checking, assumes caller will send offset >= 0
316                public void setOffset(int offset) 
317                {
318                        this.offset = offset;
319                }
320
321                public String toString() 
322                {
323                        StringBuilder sb = new StringBuilder();
324                        if (left != null) 
325                        {
326                                sb.append(left.toString()).append(' ');
327                        }
328                        if (right != null) 
329                        {
330                                sb.append(right.toString()).append(' ');
331                        }
332                        sb.append(offset).append(' ').append(direction);
333                        return sb.toString();
334                }
335        }
336        //}}}
337}