- (let (xml-start-pos xml-end-pos)
- ;; find where we should start parsing XML
- (goto-char (point-min))
- (re-search-forward "<\\?xml\\|<projects?")
- (setq xml-start-pos (match-beginning 0))
- ;; determine the start tag
- (goto-char (point-min))
- (re-search-forward "<\\(projects?\\)")
- ;; find closing tag which is also the end of the region to parse
- (search-forward (concat "</" (match-string 1) ">"))
- (setq xml-end-pos (match-end 0))
- ;; parse
- (let ((artifact-pomfile-alist
- (javaimp-build-artifact-pomfile-alist (list pom)))
- (children (javaimp-get-projects
- (xml-parse-region xml-start-pos xml-end-pos))))
- (javaimp-maven-build-children children artifact-pomfile-alist))))))
-
-(defun javaimp-make-artifact-from-xml (node)
- (javaimp-make-artifact
- (javaimp-xml-first-child (javaimp-xml-child 'groupId node))
- (javaimp-xml-first-child (javaimp-xml-child 'artifactId node))
- (javaimp-xml-first-child (javaimp-xml-child 'version node))))
-
-(defun javaimp-get-pom-file-path-lax (artifact artifact-pomfile-alist)
- (assoc-default
- artifact artifact-pomfile-alist
- (lambda (tested target)
- (or (equal target tested)
- (equal (javaimp-artifact-artifact-id target)
- (javaimp-artifact-artifact-id tested))))))
-
-(defun javaimp-maven-build-children (projects artifact-pomfile-alist)
- (let (result)
- (dolist (proj projects result)
- (let* ((artifact (javaimp-make-artifact-from-xml proj))
- (pom-file-path (javaimp-get-pom-file-path-lax
- artifact artifact-pomfile-alist))
- (build (javaimp-xml-child 'build proj))
- (source-dir (javaimp-xml-first-child
- (javaimp-xml-child 'sourceDirectory build)))
- (test-source-dir (javaimp-xml-first-child
- (javaimp-xml-child 'testSourceDirectory
- build)))
- (build-dir (javaimp-xml-first-child
- (javaimp-xml-child 'directory build)))
- (parent (javaimp-make-artifact-from-xml
- (javaimp-xml-child 'parent proj))))
- (push (javaimp-make-mod
- artifact
- pom-file-path
- (file-name-as-directory
- (if (eq system-type 'cygwin)
- (car (process-lines javaimp-cygpath-program "-u"
- source-dir))
- source-dir))
- (file-name-as-directory
- (if (eq system-type 'cygwin)
- (car (process-lines javaimp-cygpath-program "-u"
- test-source-dir))
- test-source-dir))
- (file-name-as-directory
- (if (eq system-type 'cygwin)
- (car (process-lines javaimp-cygpath-program "-u"
- build-dir))
- build-dir))
- nil nil parent nil)
- result)))))
-
-(defun javaimp-build-artifact-pomfile-alist (pom-file-list)
- "Recursively builds an alist where each element is of the
-form (\"ARTIFACT\" . \"POM-FILE-PATH\"). This is needed because
-there is no pom file path in the output of `mvn
-help:effective-pom'. Each pom file path in POM-FILE-LIST should
-be in platform's default format."
- (when pom-file-list
- (let ((pom-file (car pom-file-list))
- xml-tree project)
- (message "Saving artifact id -> pom file mapping for %s" pom-file)
- (with-temp-buffer
- (insert-file-contents pom-file)
- (setq xml-tree (xml-parse-region (point-min) (point-max))))
- (setq project (if (assq 'top xml-tree)
- (assq 'project (cddr (assq 'top xml-tree)))
- (assq 'project xml-tree)))
- (cons
- ;; this pom
- (cons (javaimp-make-artifact-from-xml project) pom-file)
- (append
- ;; submodules
- (javaimp-build-artifact-pomfile-alist
- (mapcar (lambda (submodule)
- (expand-file-name
- (concat
- ;; this pom's path
- (file-name-directory pom-file)
- ;; relative submodule directory
- (file-name-as-directory
- (let ((submodule-path (car (cddr submodule))))
- (if (eq system-type 'cygwin)
- (car (process-lines javaimp-cygpath-program "-u"
- submodule-path))
- submodule-path)))
- ;; well-known file name
- "pom.xml")))
- (javaimp-xml-child-list (assq 'modules (cddr project)) 'module)))
- ;; rest items
- (javaimp-build-artifact-pomfile-alist (cdr pom-file-list)))))))
-
-(defun javaimp-call-mvn (pom-file target handler)
+ (let ((xml-start-pos
+ (save-excursion
+ (progn
+ (goto-char (point-min))
+ (re-search-forward "<\\?xml\\|<projects?")
+ (match-beginning 0))))
+ (xml-end-pos
+ (save-excursion
+ (progn
+ (goto-char (point-min))
+ (re-search-forward "<\\(projects?\\)")
+ ;; corresponding closing tag is the end of parse region
+ (search-forward (concat "</" (match-string 1) ">"))
+ (match-end 0)))))
+ (xml-parse-region xml-start-pos xml-end-pos)))))
+
+(defun javaimp--maven-xml-parse-module (project-elt)
+ (let ((build-elt (javaimp--xml-child 'build project-elt)))
+ (make-javaimp-module
+ :id (javaimp--maven-xml-extract-id project-elt)
+ :parent-id (javaimp--maven-xml-extract-id (javaimp--xml-child 'parent project-elt))
+ ;; we set `file' slot later because raw <project> element does not contain
+ ;; pom file path, so we need to construct it during tree construction
+ :file nil
+ :final-name (javaimp--xml-first-child
+ (javaimp--xml-child 'finalName build-elt))
+ :packaging (javaimp--xml-first-child
+ (javaimp--xml-child 'packaging project-elt))
+ :source-dir (file-name-as-directory
+ (javaimp-cygpath-convert-maybe
+ (javaimp--xml-first-child
+ (javaimp--xml-child 'sourceDirectory build-elt))))
+ :test-source-dir (file-name-as-directory
+ (javaimp-cygpath-convert-maybe
+ (javaimp--xml-first-child
+ (javaimp--xml-child 'testSourceDirectory build-elt))))
+ :build-dir (file-name-as-directory
+ (javaimp-cygpath-convert-maybe
+ (javaimp--xml-first-child (javaimp--xml-child 'directory build-elt))))
+ :modules (mapcar (lambda (module-elt)
+ (javaimp--xml-first-child module-elt))
+ (javaimp--xml-children (javaimp--xml-child 'modules project-elt) 'module))
+ :dep-jars nil ; dep-jars is initialized lazily on demand
+ :load-ts (current-time))))
+
+(defun javaimp--maven-xml-extract-id (elt)
+ (make-javaimp-id
+ :group (javaimp--xml-first-child (javaimp--xml-child 'groupId elt))
+ :artifact (javaimp--xml-first-child (javaimp--xml-child 'artifactId elt))
+ :version (javaimp--xml-first-child (javaimp--xml-child 'version elt))))
+
+(defun javaimp--maven-xml-file-matches (file id parent-id)
+ (let* ((xml-tree (with-temp-buffer
+ (insert-file-contents file)
+ (xml-parse-region (point-min) (point-max))))
+ (project-elt (assq 'project xml-tree))
+ (tested-id (javaimp--maven-xml-extract-id project-elt))
+ (tested-parent-id (javaimp--maven-xml-extract-id (assq 'parent project-elt))))
+ ;; seems that the only mandatory component in tested ids is artifact, while
+ ;; group and version may be inherited and thus not presented in pom.xml
+ (let ((test (if (or (null (javaimp-id-group tested-id))
+ (null (javaimp-id-version tested-id))
+ (null (javaimp-id-group tested-parent-id))
+ (null (javaimp-id-version tested-parent-id)))
+ (progn
+ (message "File %s contains incomplete id, using lax match" file)
+ (lambda (first second)
+ (equal (javaimp-id-artifact first) (javaimp-id-artifact second))))
+ #'equal)))
+ (and (funcall test tested-id id)
+ (funcall test tested-parent-id parent-id)))))
+
+\f
+;; Maven routines
+
+(defun javaimp--maven-call (pom-file target handler)