1 ;; jde-package.el -- Java package statement generator
2 ;; $Id: jde-package.el,v 1.10 2002/12/19 06:39:44 paulk Exp $
4 ;; Copyright (C) 1998, 2000, 2001, 2002 by David Ponce
6 ;; Author: David Ponce <david@dponce.com>
7 ;; Maintainer: David Ponce <david@dponce.com>
8 ;; Paul Kinnucan <paulk@mediaone.net>
9 ;; Created: September 28 1998
11 ;; This file is not part of Emacs
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 2, or (at
16 ;; your option) any later version.
18 ;; This program is distributed in the hope that it will be useful, but
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 ;; General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with this program; see the file COPYING. If not, write to
25 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
30 ;; This package automatically generates a Java package statement. The
31 ;; package name is deducted from the current classpath setting of
32 ;; JDE. When a directory found in classpath is a root of the current
33 ;; buffer default directory, the relative path of the default
34 ;; directory from the classpath one becomes the package name by
35 ;; substituting directory separators by '.'.
39 ;; The JDE classpath setting is:
43 ;; For the file "~/java/FR/test/MyClass.java", the package name
44 ;; generated will be "FR.test".
46 ;; The JDE classpath setting is:
48 ;; ("~/java" "~/java/test")
50 ;; For the file "~/java/test/MyClass.java",
51 ;; `jde-package-default-package-comment' will be generated because
52 ;; the default package can be used.
54 ;; The JDE classpath setting is:
58 ;; For the file "/usr/java/MyClass.java", no package name will be
59 ;; generated because the directory "/usr/java" is not accessible
64 ;; M-x `jde-package-update' to update the Java package statement or
65 ;; insert a new one at beginning of current buffer.
67 ;; The function `jde-package-generate-package-statement' should be
68 ;; used in Java template to automatically generate the package
73 ;; The following variables could be set:
75 ;; - `jde-package-load-hook' hook run when package has been loaded.
77 ;; - `jde-package-package-comment' Java line comment appended to the
78 ;; generated package statement. Default is " // Generated package
81 ;; - `jde-package-default-package-comment' Java line comment generated
82 ;; when the default package is used. Default is "// Default package
85 ;; - `jde-package-search-classpath-variables' list of variables where
86 ;; to search the current classpath list. Default is
87 ;; '(`jde-compile-option-classpath' `jde-global-classpath')
91 ;; See at end of this file.
94 (defconst jde-package-unknown-package-name
96 "The string returned when a package name can't be generated.")
98 (defconst jde-package-package-regexp
100 "The regexp used to find the Java package statement.")
102 (defgroup jde-package nil
103 "jde-package package customization"
105 :prefix "jde-package-")
107 (defcustom jde-package-load-hook nil
108 "*Hook run when package has been loaded."
112 (defcustom jde-package-package-comment
113 " // Generated package name"
114 "*Java line comment appended to the generated package statement.
115 An empty string suppress the generation of this comment."
119 (defcustom jde-package-default-package-comment
120 "// Default package used"
121 "*Java line comment generated when the default package is used.
122 An empty string suppress the generation of this comment."
126 (defcustom jde-package-search-classpath-variables
127 '(jde-compile-option-classpath jde-global-classpath)
128 "*Specify the variables where to search the current classpath list.
129 The first one which has a non nil value will be used by jde-package."
131 :type '(repeat variable))
134 (defun jde-package-get-classpath ()
135 "Return the current classpath list.
136 That is to say the first non-nil value found in the variables given by
137 `jde-package-search-classpath-variables'."
138 (let ((search-in jde-package-search-classpath-variables)
140 (while (and search-in (not classpath))
141 (setq classpath (symbol-value (car search-in))
142 search-in (cdr search-in)))
145 (defun jde-package-get-directories-in-classpath ()
146 "Return the list of directories found in classpath."
149 (if (or jde-resolve-relative-paths-p
150 (not (string= path "."))) ; "." is ignored in classpath
151 (let ((path (jde-normalize-path path)))
152 (if (file-directory-p path)
153 (list (file-name-as-directory path))))))
154 (jde-package-get-classpath)))
157 (defun jde-package-seach-package-directories ()
158 "Return a list of package directory candidates or nil if not found."
159 (let ((dir (jde-normalize-path default-directory))
160 ;; case-insensitive for Windows
161 (case-fold-search (eq system-type 'windows-nt)))
164 (let ((root (regexp-quote root)))
165 (message "Seaching %S in %S..." root dir)
166 (and (string-match root dir)
167 (list (substring dir (match-end 0))))))
168 (append (jde-package-get-directories-in-classpath)
171 (file-name-as-directory
172 (jde-normalize-path p 'jde-sourcepath)))
175 (defun jde-package-best-package-candidate (candidates)
176 "Return the best package directory candidate from CANDIDATES.
177 The best is the shortest one that could be found."
178 (car (sort candidates
180 (string-match (regexp-quote dir1) dir2)))))
182 (defun jde-package-get-package-directory ()
183 "Return the package directory, if found; otherwise,
184 `jde-package-unknown-package-name'."
185 (or (jde-package-best-package-candidate
186 (jde-package-seach-package-directories))
187 jde-package-unknown-package-name))
190 (defun jde-package-convert-directory-to-package (dir)
191 "Convert directory path DIR to a valid Java package name.
192 Replace ?/ by ?. and remove extra ?/ at end."
195 (subst-char-in-string
197 (substring (file-name-as-directory dir) 0 -1)
200 (defun jde-package-generate-package-statement ()
201 "Generate a Java package statement for the Java source file in the
202 current buffer, if the package name can be determined; otherwise,
205 ;; The JDE always uses ?/ as directory separator so ensure
206 ;; [X]Emacs uses the same one when running on Windows!
207 (directory-sep-char ?/)
208 (package-name (jde-package-get-package-directory)))
210 ((string= package-name jde-package-unknown-package-name)
212 "The current directory is not accessible from classpath.")
214 ((string= package-name "")
215 (message "Default package used.")
216 jde-package-default-package-comment)
218 (message "package %s;%s"
219 (jde-package-convert-directory-to-package package-name)
220 jde-package-package-comment)))))
223 (defun jde-package-update ()
224 "Create or update the package statement in the current Java source
225 file buffer based on the file's location relative to the root of
226 the package directory as specified by one of the entries in
227 `jde-package-search-classpath-variables' or `jde-sourcepath'.
228 If these variables do not specify the root of the package directory,
229 this command does nothing. This command signals an error if the
230 major mode of the current buffer is not `jde-mode'."
232 (or (eq major-mode 'jde-mode)
233 (error "Invalid major mode found. Must be `jde-mode'"))
234 (let ((package (jde-package-generate-package-statement)))
235 (unless (string= package "")
236 (goto-char (point-min))
237 (if (re-search-forward jde-package-package-regexp nil t)
238 (replace-match package)
242 ;; Register and initialize the customization variables defined
244 (jde-update-autoloaded-symbols)
246 (provide 'jde-package)
247 (run-hooks 'jde-package-load-hook)
252 ;; $Log: jde-package.el,v $
253 ;; Revision 1.10 2002/12/19 06:39:44 paulk
254 ;; Update customization variables when jde-package.el is loaded.
256 ;; Revision 1.9 2002/12/19 06:13:15 paulk
257 ;; Fixed a bug caused by treating "." as a standard relative path character
258 ;; instead of a project file relative path character.
259 ;; Fixed and expanded some doc strings.
261 ;; Revision 1.8 2002/05/29 04:18:03 paulk
262 ;; Add the directories from jde-sourcepath to the
263 ;; directories considered when trying to derive a package name.
264 ;; Thanks to Michael N. Lipp <mnl@mnl.de>.
266 ;; Revision 1.7 2002/03/04 02:36:22 jslopez
267 ;; Removes extra log entries.(it was duplicated)
269 ;; Revision 1.6 2001/06/07 03:31:00 paulk
270 ;; Fixed NT/XEmacs incompatibility caused by XEmacs' use of back slash as the directory path separator. Thanks to David Ponce.
272 ;; Revision 1.5 2001/04/09 05:01:03 paulk
273 ;; Fixed bug in jde-package-get-directories-in-classpath that caused it to return t instead of a list when the classpath contained ".".
275 ;; Revision 1.4 2001/03/30 07:10:31 paulk
276 ;; Minor code improvement and cleanup and many checkdoc related
277 ;; cosmetic changes contributed by David Ponce.
279 ;; Revision 1.3 2001/03/13 04:23:58 paulk
282 ;; Revision 1.2 2001/02/22 03:36:30 paulk
283 ;; Removed require for jde to fix infinite recursion loading bug.
285 ;; Revision 1.1 2001/02/21 05:52:02 paulk
289 ;;; jde-package.el ends here.