Skip to content

Refactored WTP new project code to easily extend to include flex support.#1497

Merged
nbashirbello merged 18 commits intomasterfrom
newFlexProjectWizard
Mar 2, 2017
Merged

Refactored WTP new project code to easily extend to include flex support.#1497
nbashirbello merged 18 commits intomasterfrom
newFlexProjectWizard

Conversation

@nbashirbello
Copy link
Copy Markdown
Contributor

No description provided.

@nbashirbello
Copy link
Copy Markdown
Contributor Author

PR not ready for review

@nbashirbello
Copy link
Copy Markdown
Contributor Author

PR ready for review

import org.junit.Before;
import org.junit.Test;

public class StandardProjectWizardTest {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably rename this too


/**
* Collects all data needed to create and configure an App Engine Standard Project.
* Collects all data needed to create and configure an App Engine Project.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App Engine Eclipse project.

* Collects all data needed to create and configure an App Engine Project.
*/
class AppEngineStandardProjectConfig {
public class AppEngineProjectConfig {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I start to get nervous when methods get more public. This is now exposing mutable internal state publicly.

setNeedsProgressMonitor(true);
}

public abstract AppEngineWizardPage getWizardPage();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this may not be a pure getter method if it's not returning the value of the page field. If so, please rename. Maybe createWizardPage()?

private ILibraryClasspathContainerResolverService resolverService;

public AppEngineStandardProjectWizard(){
super();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this line since it's automatic

}

@Override
public AppEngineWizardPage getWizardPage() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, definitely rename this method since getters aren't creators.


try (InputStream contentXml = new FileInputStream(
"../com.google.cloud.tools.eclipse.appengine.newproject/helpContexts.xml")) {
"../com.google.cloud.tools.eclipse.appengine.newproject/standardHelpContexts.xml")) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's kind of convention to use the name helpContexts.xml. We also test if the file is included in build.properties: https://github.com/GoogleCloudPlatform/google-cloud-eclipse/blob/master/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/BasePluginXmlTest.java#L112

I think you can keep the name helpContexts.xml, and put both standard and flex help contexts into this file.

plugin.properties,\
plugin.xml,\
helpContexts.xml
standardHelpContexts.xml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

point="org.eclipse.help.contexts">
<contexts
file="helpContexts.xml">
file="standardHelpContexts.xml">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.


public abstract void sendAnalyticsPing();

public abstract IStatus validateDependencies(boolean fork, boolean cancelable);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two arguments are always true, so I don't see a great value to accept them.

}

@Override
public void sendAnalyticsPing(Composite parent) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename parent to shell, and let the caller pass parent.getShell().

@Override
public void setHelp(Composite container) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(container,
"com.google.cloud.tools.eclipse.appengine.newproject.NewStandardProjectContext"); //$NON-NLS-1$
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll have to duplicate PlatformUI.getWorkbench().getHelpSystem().setHelp(container, ...) in flex too.

Somewhat in a similar vein as https://github.com/GoogleCloudPlatform/google-cloud-eclipse/pull/1497/files#r103506394, I wonder if it's better to accept a help context ID (the literal string here) through a constructor (accepting null) and just have this code at the base class instead of having this extra setHelp() method. It's your preference though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the earlier comment.


public abstract String getCreateNewProjectOperationLabel();

public abstract IFile createProjectFiles(IProject newProject, AppEngineProjectConfig config,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a javadoc saying that this method should return the most important file that the IDE will auto-open.


public abstract void addAppEngineFacet(IProject newProject, IProgressMonitor monitor) throws CoreException;

public abstract String getCreateNewProjectOperationLabel();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be helpful to add a Javadoc about where the label will be used.

Copy link
Copy Markdown
Contributor

@chanseokoh chanseokoh Feb 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not experienced in design patterns, but I think you don't really have to have an abstract method if what you want to get is just a literal value? That is, you can have a field for this label here and let subclasses pass the value through a constructor. Thoughts?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDescription()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both approaches would work in this case. It's not uncommon for abstract methods to provide labels and descriptions.

public AppEngineStandardWizardPage() {
super();
setTitle(Messages.getString("app.engine.standard.project")); //$NON-NLS-1$
setDescription(Messages.getString("create.app.engine.standard.project")); //$NON-NLS-1$
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about passing a title and a description through arguments. (No strong opinion here.)


public AppEngineStandardProjectWizard(){
super();
setWindowTitle(Messages.getString("new.app.engine.standard.project"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You forgot to call this in the flex counterpart. How about accepting the title as an argument?

Composite container = (Composite) getControl();
PlatformUI.getWorkbench().getHelpSystem().setHelp(container,
"com.google.cloud.tools.eclipse.appengine.newproject.NewProjectContext"); //$NON-NLS-1$
setHelp(container.getShell());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be container.

setNeedsProgressMonitor(true);
}

public abstract AppEngineWizardPage createWizardPage();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which wizard page? Is this the main page?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there is only one page for creating the wtp project.

import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;

/**
* Utility to make a new Eclipse project with the App Engine Standard facets in the workspace.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed a "standard"


public abstract void addAppEngineFacet(IProject newProject, IProgressMonitor monitor) throws CoreException;

public abstract String getCreateNewProjectOperationLabel();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDescription()?

private String serviceName;

File getCloudSdkLocation() {
public File getCloudSdkLocation() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: seems odd for the Cloud SDK location to be here.


public abstract IStatus validateDependencies(boolean fork, boolean cancelable);

public abstract CreateAppEngineWtpProject getAppEngineProjectCreationOperation(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems odd. I wonder if we wouldn't be better to have an abstract createProject() operation like what you've done for validateDependencies().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chatted offline. Will leave as is since all the flex operation are workspace operations

* Returns a user visible name for the resource operation that generates the files
* for the App Engine WTP project.
*/
public abstract String getCreateNewProjectOperationLabel();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big fan of this name. getDescription()?

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

public class AppEngineFlexWizardPage extends AppEngineWizardPage {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious to see how this will be different from the AppEngineStandardWizardPage. If it's just the ping-type and help id, then we could make those configurable items passed in during creation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be expanded in a subsequent PR.

AnalyticsPingManager.getInstance().sendPing(
AnalyticsEvents.APP_ENGINE_NEW_PROJECT_WIZARD_COMPLETE,
AnalyticsEvents.APP_ENGINE_NEW_PROJECT_WIZARD_TYPE,
AnalyticsEvents.APP_ENGINE_NEW_PROJECT_WIZARD_TYPE_NATIVE);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add something here to differentiate between std and flex?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be done in a subsequent PR.



</plugin>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need two blank lines?

sdk.validateCloudSdk();
sdk.validateAppEngineJavaComponents();
page = new AppEngineStandardWizardPage();
page = createWizardPage();
Copy link
Copy Markdown
Member

@briandealwis briandealwis Mar 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My 2¢: since it's important to have the Cloud SDK validation test here, I'd prefer following the addPages() pattern here and delegate the add-page to an abstract method like addAppEnginePages(). This gives AppEngine Std and Flex the flexibility to independently add multiple pages should they need to (e.g., Flex may need to select a runtime?) without having to refactor this or figure out how to shoehorn the functionality into a single page.

@codecov-io
Copy link
Copy Markdown

codecov-io commented Mar 2, 2017

Codecov Report

Merging #1497 into master will increase coverage by 0.87%.
The diff coverage is 72.15%.

@@             Coverage Diff              @@
##             master    #1497      +/-   ##
============================================
+ Coverage     69.91%   70.79%   +0.87%     
- Complexity     1237     1349     +112     
============================================
  Files           219      230      +11     
  Lines          8796     9239     +443     
  Branches        743      790      +47     
============================================
+ Hits           6150     6541     +391     
- Misses         2331     2380      +49     
- Partials        315      318       +3
Impacted Files Coverage Δ Complexity Δ
...ls/eclipse/appengine/newproject/CodeTemplates.java 88% <ø> (ø) 9 <0> (ø)
...newproject/flex/CreateAppEngineFlexWtpProject.java 0% <0%> (ø) 0 <0> (?)
...ne/newproject/flex/AppEngineFlexProjectWizard.java 0% <0%> (ø) 0 <0> (?)
...ngine/newproject/flex/AppEngineFlexWizardPage.java 0% <0%> (ø) 0 <0> (?)
...ppengine/newproject/CreateAppEngineWtpProject.java 97.36% <100%> (ø) 5 <0> (?)
...wproject/standard/AppEngineStandardWizardPage.java 100% <100%> (ø) 3 <3> (?)
...ct/standard/CreateAppEngineStandardWtpProject.java 100% <100%> (ø) 4 <4> (?)
...e/appengine/newproject/AppEngineProjectWizard.java 64.58% <100%> (ø) 4 <2> (?)
...ipse/appengine/newproject/AppEngineWizardPage.java 85.93% <100%> (ø) 12 <0> (?)
...e/appengine/newproject/AppEngineProjectConfig.java 100% <100%> (ø) 13 <1> (?)
... and 27 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0aa34d0...ec3d553. Read the comment docs.

@nbashirbello nbashirbello merged commit 8aae460 into master Mar 2, 2017
@chanseokoh chanseokoh deleted the newFlexProjectWizard branch April 3, 2017 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants