/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2010 Oracle and/or its affiliates. All rights reserved. * * Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. * * Contributor(s): * * Portions Copyrighted 2008 Sun Microsystems, Inc. */ package org.netbeans.modules.ruby.rubyproject.rake; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import org.netbeans.api.project.Project; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem; import org.openide.util.Exceptions; import org.openide.util.io.ReaderInputStream; final class RakeTaskReader { private final Project project; RakeTaskReader(final Project project) { this.project = project; } Set<RakeTask> getRakeTaskTree() { return getRakeTaskTree(true); } Set<RakeTask> getRakeTaskTree(final boolean withDescriptionOnly) { try { String rawOutput = rawRead(); Set<RakeTask> tasks = rawOutput == null ? Collections.<RakeTask>emptySet() : parseTasks(new StringReader(rawOutput)); if (withDescriptionOnly) { for (Iterator<RakeTask> it = tasks.iterator(); it.hasNext();) { RakeTask task = it.next(); if (!task.isNameSpace() && task.getDescription() == null) { it.remove(); } } } return tasks; } catch (IOException ioe) { Exceptions.printStackTrace(ioe); return Collections.emptySet(); } } String rawRead() { final FileObject projectDir = project.getProjectDirectory(); try { final StringBuilder sb = new StringBuilder(5000); projectDir.getFileSystem().runAtomicAction(new FileSystem.AtomicAction() { public void run() throws IOException { FileObject rakeTasksFile = projectDir.getFileObject(RakeSupport.RAKE_D_OUTPUT); if (rakeTasksFile == null) { return; } BufferedReader reader = null; try { InputStream is = rakeTasksFile.getInputStream(); reader = new BufferedReader(new InputStreamReader(is)); while (true) { String line = reader.readLine(); if (line == null) { break; } sb.append(line); sb.append('\n'); } } finally { if (reader != null) { reader.close(); } } } }); return sb.length() > 0 ? sb.toString() : null; } catch (IOException ioe) { Exceptions.printStackTrace(ioe); return null; } } private static Set<RakeTask> parseTasks(Reader is) throws IOException { Properties tasksProps = new Properties(); tasksProps.load(new ReaderInputStream(is)); Set<RakeTask> tasks = new TreeSet<RakeTask>(); Map<String, RakeTask> map = new HashMap<String, RakeTask>(50); Set<String> processedTasks = new HashSet<String>(); for (Map.Entry<Object, Object> entry : tasksProps.entrySet()) { String task = (String) entry.getKey(); String description = (String) entry.getValue(); if ("".equals(description)) { description = null; } if (!processedTasks.add(task)) { continue; } // Tokenize into categories (db:fixtures:load -> db | fixtures | load) RakeTask parent = null; String[] path = task.split(":"); // NOI18N StringBuilder sb = new StringBuilder(); for (int i = 0; i < (path.length - 1); i++) { if (sb.length() > 0) { sb.append(':'); } sb.append(path[i]); String folderPath = sb.toString(); RakeTask p = map.get(folderPath); if (p == null) { RakeTask r = RakeTask.newNameSpace(path[i]); if (parent == null) { tasks.add(r); } else { parent.addChild(r); } map.put(folderPath, r); parent = r; } else { parent = p; } } RakeTask t = new RakeTask(task, path[path.length - 1], description); if (parent != null) { parent.addChild(t); } else { tasks.add(t); } } return tasks; } }