今天同事問我在Maven構建Theme時Liferay架構預設資源檔從何處擷取,我對比了下使用Ant來編譯部署Theme和使用Maven來編譯部署Theme的過程,發現:在複製架構預設資源檔時,居然是完全不同的策略!
Ant 複製Liferay預設資源檔的策略:
大家都知道,在用Ant編譯Theme時,我們程式員需要在_diffs目錄下添加一些和Liferay架構不同的資源檔,而Liferay架構本身的資源檔都會從 $LIFERAY_HOME\tomcat-7.0.23\webapps\ROOT\html\themes 目錄下複製到你的建立theme項目。
- <copy todir="docroot" overwrite="true">
- <fileset
- dir="${app.server.portal.dir}/html/themes/_styled"
- />
- </copy>
Maven複製Liferay預設資源檔的策略:
Maven不會從ROOT/html/themes複製資源檔,相反,它會從一個叫portal-web-6.1.0.war中複製過來的。這個war包在你機器~/.m2/repository指向的本地倉庫中:比如我的就在 C:\Documents and Settings\charles.wang\.m2\repository\com\liferay\portal\portal-web\6.1.0 目錄下。
而這一切都發生在liferay-maven-plugin生命週期的theme-merge階段,當我們吧速度放慢一萬倍,我們就可以清楚的看到細節了(太極的精髓啊)。
theme-merge階段用於吧我們自己開發的資源檔+系統資源檔merge到artifact中:
首先它會定義相關的環境配置:
- [DEBUG] -----------------------------------------------------------------------
- [DEBUG] Goal: com.liferay.maven.plugins:liferay-maven-plugin:6.1.0:theme-merge (default)
- [DEBUG] Style: Regular
- [DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
- <configuration>
- <liferayVersion>6.1.0</liferayVersion>
- <localArtifactRepository>${localRepository}</localArtifactRepository>
- <parentTheme default-value="_styled">_styled</parentTheme>
- <remoteArtifactRepositories>${project.remoteArtifactRepositories}</remoteArtifactRepositories>
- <themeType default-value="vm">vm</themeType>
- <webappDir>${project.build.directory}/${project.build.finalName}</webappDir>
- <workDir>${project.build.directory}/liferay-theme/work</workDir>
- </configuration>
最終執行theme-merge對應的類,位於liferay-maven-plugin-6.1.0.jar的ThemeMergeMojo類,類中用到的所有的參數都是寫在設定檔然後傳遞進去的:
這些參數和你的運行Maven命令的機器有關,因為你畢竟設定了~/.m2/repository本地倉庫,而且你也設定了pom.xml,在我機器上這些參數的細節可以見02-16行:
- [DEBUG] Configuring mojo 'com.liferay.maven.plugins:liferay-maven-plugin:6.1.0:theme-merge' with basic configurator -->
- [DEBUG] (f) liferayVersion = 6.1.0
- [DEBUG] (f) localArtifactRepository = id: local
- url: file:///C:/Documents%20and%20Settings/charles.wang/.m2/repository/
- layout: none
-
- [DEBUG] (f) parentTheme = _styled
- [DEBUG] (f) remoteArtifactRepositories = [ id: central
- url: http://repo1.maven.org/maven2
- layout: default
- snapshots: [enabled => false, update => daily]
- releases: [enabled => true, update => daily]
- ]
- [DEBUG] (f) themeType = vm
- [DEBUG] (f) webappDir = D:\WalmartProject\maven-build-theme\target\maven-build-theme-0.0.1-SNAPSHOT
- [DEBUG] (f) workDir = D:\WalmartProject\maven-build-theme\target\liferay-theme\work
- [DEBUG] -- end configuration –
- [DEBUG] Expanding: C:\Documents and Settings\charles.wang\.m2\repository\com\liferay\portal\portal-web\6.1.0\portal-web-6.1.0.war into D:\WalmartProject\maven-build-theme\target\liferay-theme\work 這一行就是從何處擷取資源檔的日誌)
然後第18行就顯示了如何從portal-web-6.1.0.war包中吧相關的靜態資源複製到你自訂的theme應用下,這段日誌被以下代碼片斷執行,它先定義了要在war包中擷取(include)和排除(exclude)哪些資源:
- protected void doExecute() throws Exception {
- if (!this.workDir.exists()) {
- this.workDir.mkdirs();
- }
-
- String parentThemeGroupId = "com.liferay.portal";
- String parentThemeArtifactId = "portal-web";
- String parentThemeVersion = this.liferayVersion;
-
- String[] excludes = { "html/themes/classic/_diffs/**", "html/themes/control_panel/_diffs/**" };
-
- String[] includes = { "html/themes/_unstyled/**", "html/themes/_styled/**", "html/themes/classic/**", "html/themes/control_panel/**" };
然後建立一個Artifact對象讓其指向~/.m2/repository 倉庫中的portal-web-6.1.0.war包:
- Artifact artifact = this.artifactFactory.createArtifact(parentThemeGroupId, parentThemeArtifactId, parentThemeVersion, "", "war");
然後解開這個war包,並且按照已經定義的includes和excludes從中抽取資源:
- this.artifactResolver.resolve(artifact, this.remoteArtifactRepositories, this.localArtifactRepository);
-
- UnArchiver unArchiver = this.archiverManager.getUnArchiver(artifact.getFile());
-
- unArchiver.setDestDirectory(this.workDir);
- unArchiver.setSourceFile(artifact.getFile());
-
- IncludeExcludeFileSelector includeExcludeFileSelector = new IncludeExcludeFileSelector();
-
- includeExcludeFileSelector.setExcludes(excludes);
- includeExcludeFileSelector.setIncludes(includes);
-
- unArchiver.setFileSelectors(new FileSelector[] { includeExcludeFileSelector });
-
- unArchiver.extract();
最後做一些複製工作,它吧剛才抽取出來的資源檔都複製到我們自訂的theme應用中:
- FileUtils.copyDirectory(new File(this.workDir, "html/themes/_unstyled"), this.webappDir);
- FileUtils.copyDirectory(new File(this.workDir, "html/themes/_styled"), this.webappDir);
- FileUtils.copyDirectory(new File(this.workDir, "html/themes/" + this.parentTheme), this.webappDir);
- FileUtils.copyDirectory(this.workDir, this.webappDir);
所以,我們就可以在自訂的theme中既能看到自己定義的資源檔,又可以看到Liferay內建theme的資源檔了。