Package org.jboss.forge.scaffold.plugins

Source Code of org.jboss.forge.scaffold.plugins.ScaffoldPlugin

/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.forge.scaffold.plugins;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.enterprise.event.Event;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.persistence.Entity;

import org.jboss.forge.env.Configuration;
import org.jboss.forge.parser.java.JavaClass;
import org.jboss.forge.parser.java.JavaSource;
import org.jboss.forge.parser.java.util.Strings;
import org.jboss.forge.project.Facet;
import org.jboss.forge.project.Project;
import org.jboss.forge.project.facets.PackagingFacet;
import org.jboss.forge.project.facets.WebResourceFacet;
import org.jboss.forge.project.facets.events.InstallFacets;
import org.jboss.forge.resources.FileResource;
import org.jboss.forge.resources.Resource;
import org.jboss.forge.resources.java.JavaResource;
import org.jboss.forge.scaffold.ScaffoldProvider;
import org.jboss.forge.scaffold.events.ScaffoldGeneratedResources;
import org.jboss.forge.scaffold.plugins.shell.ScaffoldProviderCompleter;
import org.jboss.forge.shell.PromptType;
import org.jboss.forge.shell.ShellMessages;
import org.jboss.forge.shell.ShellPrintWriter;
import org.jboss.forge.shell.ShellPrompt;
import org.jboss.forge.shell.plugins.Alias;
import org.jboss.forge.shell.plugins.Command;
import org.jboss.forge.shell.plugins.Current;
import org.jboss.forge.shell.plugins.Help;
import org.jboss.forge.shell.plugins.Option;
import org.jboss.forge.shell.plugins.Plugin;
import org.jboss.forge.shell.plugins.RequiresFacet;
import org.jboss.forge.shell.plugins.RequiresProject;
import org.jboss.forge.shell.plugins.SetupCommand;
import org.jboss.forge.shell.plugins.Topic;
import org.jboss.forge.shell.util.ConstraintInspector;

/**
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*
*/
@Alias("scaffold")
@Topic("UI Generation & Scaffolding")
@Help("Faces UI scaffolding")
@RequiresProject
@RequiresFacet(ScaffoldProvider.class)
public class ScaffoldPlugin implements Plugin
{
   @Inject
   @Current
   private Resource<?> currentResource;

   @Inject
   private Configuration config;

   @Inject
   private Project project;

   @Inject
   private ShellPrompt prompt;

   @Inject
   private ShellPrintWriter writer;

   @Inject
   private Instance<ScaffoldProvider> impls;

   @Inject
   private Event<ScaffoldGeneratedResources> generatedEvent;

   @Inject
   private Event<InstallFacets> installFacets;

   @SetupCommand
   public void setup(
            @Option(name = "targetDir") String targetDir,
            @Option(name = "scaffoldType", required = false, completer = ScaffoldProviderCompleter.class) final String scaffoldType,
            @Option(flagOnly = true, name = "overwrite") final boolean overwrite,
            @Option(name = "usingTemplate") final Resource<?> template)
   {
      ScaffoldProvider provider = getScaffoldType(scaffoldType);
      targetDir = selectTargetDir(provider, targetDir);
      verifyTemplate(provider, template);
      List<Resource<?>> generatedResources = provider.setup(targetDir, template, overwrite);

      // TODO give plugins a chance to react to generated resources, use event bus?
      if (!generatedResources.isEmpty())
      {
         generatedEvent.fire(new ScaffoldGeneratedResources(provider, prepareResources(generatedResources)));
      }
   }

   @Command("indexes")
   public void generateIndex(
            @Option(name = "targetDir") String targetDir,
            @Option(name = "scaffoldType", required = false, completer = ScaffoldProviderCompleter.class) final String scaffoldType,
            @Option(flagOnly = true, name = "overwrite") final boolean overwrite,
            @Option(name = "usingTemplate") final Resource<?> template)
   {
      ScaffoldProvider provider = getScaffoldType(scaffoldType);
      targetDir = selectTargetDir(provider, targetDir);
      verifyTemplate(provider, template);
      List<Resource<?>> generatedResources = provider.generateIndex(targetDir, template, overwrite);

      // TODO give plugins a chance to react to generated resources, use event bus?
      if (!generatedResources.isEmpty())
      {
         generatedEvent.fire(new ScaffoldGeneratedResources(provider, prepareResources(generatedResources)));
      }
   }

   @Command("templates")
   public void generateTemplates(
            @Option(name = "targetDir") String targetDir,
            @Option(name = "scaffoldType", required = false, completer = ScaffoldProviderCompleter.class) final String scaffoldType,

            @Option(flagOnly = true, name = "overwrite") final boolean overwrite)
   {
      ScaffoldProvider provider = getScaffoldType(scaffoldType);
      targetDir = selectTargetDir(provider, targetDir);
      List<Resource<?>> generatedResources = provider.generateTemplates(targetDir, overwrite);

      // TODO give plugins a chance to react to generated resources, use event bus?
      if (!generatedResources.isEmpty())
      {
         generatedEvent.fire(new ScaffoldGeneratedResources(provider, prepareResources(generatedResources)));
      }
   }

   @Command("from-entity")
   public void generateFromEntity(
            @Option(required = false) JavaResource[] targets,
            @Option(name = "targetDir") String targetDir,
            @Option(name = "scaffoldType", required = false, completer = ScaffoldProviderCompleter.class) final String scaffoldType,
            @Option(flagOnly = true, name = "overwrite") final boolean overwrite,
            @Option(name = "usingTemplate") final Resource<?> template) throws FileNotFoundException
   {
      if (((targets == null) || (targets.length < 1)) && (currentResource instanceof JavaResource))
      {
         targets = new JavaResource[] { (JavaResource) currentResource };
      }

      List<JavaResource> javaTargets = selectTargets(targets);
      if (javaTargets.isEmpty())
      {
         ShellMessages.error(writer, "Must specify a domain @Entity on which to operate.");
         return;
      }

      ScaffoldProvider provider = getScaffoldType(scaffoldType);
      targetDir = selectTargetDir(provider, targetDir);
      verifyTemplate(provider, template);

      for (JavaResource jr : javaTargets)
      {
         JavaClass entity = (JavaClass) (jr).getJavaSource();
         List<Resource<?>> generatedResources = provider.generateFromEntity(targetDir, template, entity, overwrite);

         // TODO give plugins a chance to react to generated resources, use event bus?
         if (!generatedResources.isEmpty())
         {
            generatedEvent.fire(new ScaffoldGeneratedResources(provider, prepareResources(generatedResources)));
         }

         ShellMessages.success(writer, "Generated UI for [" + entity.getQualifiedName() + "]");
      }

   }

   private String selectTargetDir(ScaffoldProvider provider, String target)
   {
      if (provider == null)
      {
         throw new RuntimeException("Selected scaffold provider was null. Re-run with '--scaffoldType ...'");
      }

      String targetDirKey = getTargetDirConfigKey(provider);

      if (Strings.isNullOrEmpty(target))
      {
         target = config.getString(targetDirKey);
         if (Strings.isNullOrEmpty(target))
         {
            String finalName = project.getFacet(PackagingFacet.class).getFinalName();
            target = prompt.promptCommon(
                     "Create scaffold in which sub-directory of web-root? (e.g. http://localhost:8080/" + finalName
                              + "/DIR)", PromptType.FILE_PATH, "/");
         }
      }
     
      if(!Strings.isNullOrEmpty(target))
      {
         config.setProperty(targetDirKey, target);
         if (!target.startsWith("/"))
            target = "/" + target;
         if (target.endsWith("/"))
            target = target.substring(0, target.length() - 1);
      }
      return target;
   }

   private String getTargetDirConfigKey(ScaffoldProvider provider)
   {
      return provider.getClass().getName() + "_targetDir";
   }

   private ScaffoldProvider getScaffoldType(String scaffoldType)
   {
      ScaffoldProvider scaffoldImpl = null;

      Collection<Facet> facets = project.getFacets();
      List<ScaffoldProvider> detectedScaffolds = new ArrayList<ScaffoldProvider>();
      for (Facet facet : facets)
      {
         if (facet instanceof ScaffoldProvider)
         {
            detectedScaffolds.add((ScaffoldProvider) facet);
            if (ConstraintInspector.getName(facet.getClass()).equals(scaffoldType))
            {
               scaffoldImpl = (ScaffoldProvider) facet;
            }
         }
      }

      if (scaffoldImpl == null)
      {
         List<String> detectedScaffoldNames = new ArrayList<String>();
         for (ScaffoldProvider sp : detectedScaffolds)
         {
            detectedScaffoldNames.add(ConstraintInspector.getName(sp.getClass()));
         }

         if (detectedScaffolds.size() > 1)
         {
            String name = prompt.promptChoiceTyped("Use which previously installed scaffold provider?",
                     detectedScaffoldNames, detectedScaffoldNames.get(detectedScaffoldNames.size() - 1));

            for (ScaffoldProvider sp : detectedScaffolds)
            {
               if (name.equals(ConstraintInspector.getName(sp.getClass())))
               {
                  scaffoldImpl = sp;
                  break;
               }
            }
         }
         else if (!detectedScaffolds.isEmpty())
         {
            scaffoldImpl = detectedScaffolds.get(0);
            ShellMessages.info(writer,
                     "Using currently installed scaffold [" + ConstraintInspector.getName(scaffoldImpl.getClass())
                              + "]");
         }
      }

      /*
       * Resolve scaffoldType
       */
      if ((scaffoldImpl == null && scaffoldType == null)
               && prompt.promptBoolean("No scaffold type was selected, use default [JavaServer Faces]?"))
      {
         scaffoldType = "faces";
         for (ScaffoldProvider type : impls)
         {
            if (ConstraintInspector.getName(type.getClass()).equals(scaffoldType))
            {
               scaffoldImpl = type;
            }
         }
      }
      else if (scaffoldImpl == null && scaffoldType != null)
      {
         for (ScaffoldProvider type : impls)
         {
            if (ConstraintInspector.getName(type.getClass()).equals(scaffoldType))
            {
               scaffoldImpl = type;
            }
         }
      }

      if (scaffoldImpl == null)
      {
         throw new RuntimeException(
                  "No scaffold installed was detected, and no scaffold type was selected; re-run with '--scaffoldType ...' ");
      }

      /*
       * Perform installation
       */
      if (!project.hasFacet(scaffoldImpl.getClass())
               && prompt.promptBoolean("Scaffold provider [" + scaffoldType + "] is not installed. Install it?"))
      {
         installFacets.fire(new InstallFacets(scaffoldImpl.getClass()));
      }
      else if (!project.hasFacet(scaffoldImpl.getClass()))
      {
         throw new RuntimeException("Aborted.");
      }

      if (project.hasFacet(WebResourceFacet.class))
      {
         FileResource<?> favicon = project.getFacet(WebResourceFacet.class).getWebResource("/favicon.ico");
         if (!favicon.exists())
         {
            favicon.setContents(getClass().getResourceAsStream("/org/jboss/forge/scaffold/favicon.ico"));
         }
      }

      return project.getFacet(scaffoldImpl.getClass());
   }

   private List<JavaResource> selectTargets(Resource<?>[] targets) throws FileNotFoundException
   {
      List<JavaResource> results = new ArrayList<JavaResource>();
      if (targets == null)
      {
         targets = new Resource<?>[] {};
      }
      for (Resource<?> r : targets)
      {
         if (r instanceof JavaResource)
         {
            JavaSource<?> entity = ((JavaResource) r).getJavaSource();

            if (entity instanceof JavaClass)
            {
               if (entity.hasAnnotation(Entity.class))
               {
                  results.add((JavaResource) r);
               }
               else
               {
                  displaySkippingResourceMsg(entity);
               }
            }
            else
            {
               displaySkippingResourceMsg(entity);
            }
         }
      }
      return results;
   }

   private void displaySkippingResourceMsg(final JavaSource<?> entity)
   {
      ShellMessages.info(writer, "Skipped non-@Entity Java resource [" + entity.getQualifiedName() + "]");
   }

   private List<Resource<?>> prepareResources(final List<Resource<?>> generatedResources)
   {
      List<Integer> nullIndexes = new ArrayList<Integer>();
      for (int i = 0; i < generatedResources.size(); i++)
      {
         Resource<?> r = generatedResources.get(i);
         if (r == null)
         {
            nullIndexes.add(i);
         }
      }

      for (Integer index : nullIndexes)
      {
         generatedResources.remove(index);
      }
      return generatedResources;
   }

   private void verifyTemplate(final ScaffoldProvider provider, final Resource<?> template)
   {
      if (template != null)
      {
         if (!template.exists())
         {
            throw new IllegalArgumentException("Template [" + template.getName()
                     + "] does not exist. You must select a template that exists, or use "
                     + "the default template (do not specify a template.)");
         }

         if (!provider.getTemplateStrategy().compatibleWith(template))
         {
            throw new IllegalStateException("Template [" + template.getName() + "] is not compatible with provider ["
                     + ConstraintInspector.getName(provider.getClass()) + "]");
         }
      }
   }
}
TOP

Related Classes of org.jboss.forge.scaffold.plugins.ScaffoldPlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.