1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.eclipse.adt.internal.wizards.templates;
18 
19 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_BUILD_API;
20 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_COPY_ICONS;
21 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API;
22 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API_LEVEL;
23 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME;
24 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_TARGET_API;
25 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_LIBRARY_PROJECT;
26 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_NEW_PROJECT;
27 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewTemplateWizard.BLANK_ACTIVITY;
28 
29 import com.android.annotations.NonNull;
30 import com.android.annotations.Nullable;
31 import com.android.ide.eclipse.adt.internal.assetstudio.ConfigureAssetSetPage;
32 import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState;
33 import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
34 import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
35 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
36 import com.android.sdklib.IAndroidTarget;
37 
38 import org.eclipse.core.resources.IProject;
39 import org.eclipse.core.runtime.CoreException;
40 import org.eclipse.core.runtime.IProgressMonitor;
41 import org.eclipse.ltk.core.refactoring.Change;
42 import org.eclipse.ltk.core.refactoring.NullChange;
43 
44 import java.io.File;
45 import java.util.Collections;
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Set;
51 
52 /**
53  * Value object which holds the current state of the wizard pages for the
54  * {@link NewTemplateWizard}
55  */
56 public class NewTemplateWizardState {
57     /** Template handler responsible for instantiating templates and reading resources */
58     private TemplateHandler mTemplateHandler;
59 
60     /** Configured parameters, by id */
61     public final Map<String, Object> parameters = new HashMap<String, Object>();
62 
63     /** Configured defaults for the parameters, by id */
64     public final Map<String, String> defaults = new HashMap<String, String>();
65 
66     /** Ids for parameters which should be hidden (because the client wizard already
67      * has information for these parameters) */
68     public final Set<String> hidden = new HashSet<String>();
69 
70     /**
71      * The chosen project (which may be null if the wizard page is being
72      * embedded in the new project wizard)
73      */
74     public IProject project;
75 
76     /** The minimum API level to use for this template */
77     public int minSdkLevel;
78 
79     /** Location of the template being created */
80     private File mTemplateLocation;
81 
82     /**
83      * State for the asset studio wizard, used to create custom icons provided
84      * the icon requests it with an {@code <icons>} element
85      */
86     private CreateAssetSetWizardState mIconState;
87 
88     /**
89      * Create a new state object for use by the {@link NewTemplatePage}
90      */
NewTemplateWizardState()91     public NewTemplateWizardState() {
92         parameters.put(IS_NEW_PROJECT, false);
93     }
94 
95     @NonNull
getTemplateHandler()96     TemplateHandler getTemplateHandler() {
97         if (mTemplateHandler == null) {
98             File inputPath;
99             if (mTemplateLocation != null) {
100                 inputPath = mTemplateLocation;
101             } else {
102                 // Default
103                 inputPath = TemplateManager.getTemplateLocation(BLANK_ACTIVITY);
104             }
105             mTemplateHandler = TemplateHandler.createFromPath(inputPath);
106         }
107 
108         return mTemplateHandler;
109     }
110 
111     /** Sets the current template */
setTemplateLocation(File file)112     void setTemplateLocation(File file) {
113         if (!file.equals(mTemplateLocation)) {
114             mTemplateLocation = file;
115             mTemplateHandler = null;
116         }
117     }
118 
119     /** Returns the current template */
getTemplateLocation()120     File getTemplateLocation() {
121         return mTemplateLocation;
122     }
123 
124     /** Returns the min SDK version to use */
getMinSdk()125     int getMinSdk() {
126         if (project == null) {
127             return -1;
128         }
129         ManifestInfo manifest = ManifestInfo.get(project);
130         return manifest.getMinSdkVersion();
131     }
132 
133     /** Returns the build API version to use */
getBuildApi()134     int getBuildApi() {
135         if (project == null) {
136             return -1;
137         }
138         IAndroidTarget target = Sdk.getCurrent().getTarget(project);
139         if (target != null) {
140             return target.getVersion().getApiLevel();
141         }
142 
143         return getMinSdk();
144     }
145 
146     /** Computes the changes this wizard will make */
147     @NonNull
computeChanges()148     List<Change> computeChanges() {
149         if (project == null) {
150             return Collections.emptyList();
151         }
152 
153         ManifestInfo manifest = ManifestInfo.get(project);
154         parameters.put(ATTR_PACKAGE_NAME, manifest.getPackage());
155         parameters.put(ATTR_MIN_API, manifest.getMinSdkName());
156         parameters.put(ATTR_MIN_API_LEVEL, manifest.getMinSdkVersion());
157         parameters.put(ATTR_TARGET_API, manifest.getTargetSdkVersion());
158         parameters.put(ATTR_BUILD_API, getBuildApi());
159         parameters.put(ATTR_COPY_ICONS, mIconState == null);
160         ProjectState projectState = Sdk.getProjectState(project);
161         parameters.put(IS_LIBRARY_PROJECT,
162                 projectState != null ? projectState.isLibrary() : false);
163 
164         TemplateHandler.addDirectoryParameters(parameters, project);
165 
166         List<Change> changes = getTemplateHandler().render(project, parameters);
167 
168         if (mIconState != null) {
169             String title = String.format("Generate icons (res/drawable-<density>/%1$s.png)",
170                     mIconState.outputName);
171             changes.add(new NullChange(title) {
172                 @Override
173                 public Change perform(IProgressMonitor pm) throws CoreException {
174                     ConfigureAssetSetPage.generateIcons(mIconState.project,
175                             mIconState, false, null);
176 
177                     // Not undoable: just return null instead of an undo-change.
178                     return null;
179                 }
180             });
181 
182         }
183 
184         return changes;
185     }
186 
187     @NonNull
getIconState()188     CreateAssetSetWizardState getIconState() {
189         if (mIconState == null) {
190             TemplateHandler handler = getTemplateHandler();
191             if (handler != null) {
192                 TemplateMetadata template = handler.getTemplate();
193                 if (template != null) {
194                     mIconState = template.getIconState(project);
195                 }
196             }
197         }
198 
199         return mIconState;
200     }
201 
202     /**
203      * Updates the icon state, such as the output name, based on other parameter settings
204      * @param evaluator the string evaluator, or null if none exists
205      */
updateIconState(@ullable StringEvaluator evaluator)206     public void updateIconState(@Nullable StringEvaluator evaluator) {
207         TemplateMetadata template = getTemplateHandler().getTemplate();
208         if (template != null) {
209             if (evaluator == null) {
210                 evaluator = new StringEvaluator();
211             }
212             template.updateIconName(template.getParameters(), evaluator);
213         }
214     }
215 }
216