1 /* 2 * Packages.java 3 * 4 * Copyright (C) 2002-2007 Peter Graves <peter@armedbear.org> 5 * $Id$ 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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * As a special exception, the copyright holders of this library give you 22 * permission to link this library with independent modules to produce an 23 * executable, regardless of the license terms of these independent 24 * modules, and to copy and distribute the resulting executable under 25 * terms of your choice, provided that you also meet, for each linked 26 * independent module, the terms and conditions of the license of that 27 * module. An independent module is a module which is not derived from 28 * or based on this library. If you modify this library, you may extend 29 * this exception to your version of the library, but you are not 30 * obligated to do so. If you do not wish to do so, delete this 31 * exception statement from your version. 32 */ 33 34 package org.armedbear.lisp; 35 36 import static org.armedbear.lisp.Lisp.*; 37 38 import java.util.ArrayList; 39 import java.util.HashMap; 40 import java.util.Iterator; 41 import java.util.List; 42 43 public final class Packages 44 { 45 private static final ArrayList<Package> packages = new ArrayList<Package>(); 46 private static final HashMap<String,Package> map = new HashMap<String,Package>(); 47 createPackage(String name)48 public static final synchronized Package createPackage(String name) 49 { 50 return createPackage(name, 0); 51 } 52 createPackage(String name, int size)53 public static final synchronized Package createPackage(String name, int size) 54 { 55 Package pkg = (Package) map.get(name); 56 if (pkg == null) 57 { 58 pkg = size != 0 ? new Package(name, size) : new Package(name); 59 packages.add(pkg); 60 map.put(name, pkg); 61 } 62 else 63 Debug.trace("package " + name + " already exists"); 64 return pkg; 65 } 66 addPackage(Package pkg)67 public static final synchronized void addPackage(Package pkg) 68 69 { 70 final String name = pkg.getName(); 71 if (map.get(name) != null) 72 { 73 error(new LispError("A package named " + name + " already exists.")); 74 return; 75 } 76 packages.add(pkg); 77 map.put(name, pkg); 78 List nicknames = pkg.getNicknames(); 79 if (nicknames != null) 80 { 81 for (Iterator it = nicknames.iterator(); it.hasNext();) 82 { 83 String nickname = (String) it.next(); 84 addNickname(pkg, nickname); 85 } 86 } 87 } 88 89 /** 90 Returns the current package of the current LispThread. 91 92 Intended to be used from Java code manipulating an Interpreter 93 instance. 94 */ findPackage(String name)95 public static final synchronized Package findPackage(String name) { 96 return getCurrentPackage().findPackage(name); 97 } 98 99 // Finds package named `name'. Returns null if package doesn't exist. 100 // Called by Package.findPackage after checking package-local package 101 // nicknames. findPackageGlobally(String name)102 static final synchronized Package findPackageGlobally(String name) 103 { 104 return (Package) map.get(name); 105 } 106 makePackage(String name)107 public static final synchronized Package makePackage(String name) 108 109 { 110 if (map.get(name) != null) 111 { 112 error(new LispError("A package named " + name + " already exists.")); 113 // Not reached. 114 return null; 115 } 116 Package pkg = new Package(name); 117 packages.add(pkg); 118 map.put(name, pkg); 119 return pkg; 120 } 121 addNickname(Package pkg, String nickname)122 public static final synchronized void addNickname(Package pkg, String nickname) 123 124 { 125 Object obj = map.get(nickname); 126 if (obj != null && obj != pkg) 127 { 128 error(new PackageError("A package named " + nickname + " already exists.", new SimpleString(nickname))); 129 return; 130 } 131 map.put(nickname, pkg); 132 } 133 134 // Removes name and nicknames from map, removes pkg from packages. deletePackage(Package pkg)135 public static final synchronized boolean deletePackage(Package pkg) 136 { 137 String name = pkg.getName(); 138 if (name != null) 139 { 140 map.remove(name); 141 List nicknames = pkg.getNicknames(); 142 if (nicknames != null) 143 { 144 for (Iterator it = nicknames.iterator(); it.hasNext();) 145 { 146 String nickname = (String) it.next(); 147 map.remove(nickname); 148 } 149 } 150 packages.remove(pkg); 151 return true; 152 } 153 return false; 154 } 155 listAllPackages()156 public static final synchronized LispObject listAllPackages() 157 { 158 LispObject result = NIL; 159 for (Package pkg : packages) { 160 result = new Cons(pkg, result); 161 } 162 return result; 163 } 164 getAllPackages()165 public static final synchronized Package[] getAllPackages() 166 { 167 Package[] array = new Package[packages.size()]; 168 packages.toArray(array); 169 return array; 170 } 171 getPackagesNicknamingPackage(Package thePackage)172 public static final synchronized LispObject getPackagesNicknamingPackage(Package thePackage) 173 { 174 LispObject result = NIL; 175 for (Package pkg : packages) { 176 for (Package nicknamedPackage : pkg.getLocallyNicknamedPackages()) { 177 if (thePackage.equals(nicknamedPackage)) { 178 result = new Cons(pkg, result); 179 } 180 } 181 } 182 return result; 183 } 184 } 185