Package juzu.plugin.shiro.impl

Source Code of juzu.plugin.shiro.impl.ShiroMetaModelPlugin

/*
*
* 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 juzu.plugin.shiro.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import juzu.impl.common.JSON;
import juzu.impl.common.Name;
import juzu.impl.common.Tools;
import juzu.impl.compiler.ElementHandle;
import juzu.impl.compiler.ProcessingContext;
import juzu.impl.metamodel.AnnotationKey;
import juzu.impl.metamodel.AnnotationState;
import juzu.impl.plugin.application.metamodel.ApplicationMetaModel;
import juzu.impl.plugin.application.metamodel.ApplicationMetaModelPlugin;
import juzu.impl.plugin.controller.metamodel.ControllerMetaModel;
import juzu.impl.plugin.controller.metamodel.ControllersMetaModel;
import juzu.impl.plugin.controller.metamodel.HandlerMetaModel;
import juzu.plugin.shiro.Login;
import juzu.plugin.shiro.Logout;
import juzu.plugin.shiro.Shiro;

import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresGuest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;

/**
* @author <a href="mailto:haithanh0809@gmail.com">Nguyen Thanh Hai</a>
* @version $Id$
*
*/
public class ShiroMetaModelPlugin extends ApplicationMetaModelPlugin {
  /** . */
  private final Map<ElementHandle.Package, JSON> enableMap = new HashMap<ElementHandle.Package, JSON>();

  /** . */
  private final Map<ElementHandle<?>, Map<AnnotationKey, AnnotationState>> methods =
    new HashMap<ElementHandle<?>, Map<AnnotationKey, AnnotationState>>();

  /** . */
  private final Map<ElementHandle<?>, Map<AnnotationKey, AnnotationState>> controllers =
    new HashMap<ElementHandle<?>, Map<AnnotationKey, AnnotationState>>();

  public ShiroMetaModelPlugin() {
    super("shiro");
  }

  @Override
  public Set<Class<? extends java.lang.annotation.Annotation>> init(ProcessingContext env) {
    return Tools.<Class<? extends java.lang.annotation.Annotation>> set(Shiro.class, RequiresGuest.class,
      RequiresUser.class, RequiresAuthentication.class, RequiresPermissions.class, RequiresRoles.class, Login.class,
      Logout.class);
  }

  @Override
  public void processAnnotationAdded(ApplicationMetaModel metaModel, AnnotationKey key, AnnotationState added) {
    ElementHandle.Package handle = metaModel.getHandle();
    if (key.getType().equals(Name.create(Shiro.class))) {
      JSON json = new JSON();
      json.set("rememberMe", added.get("rememberMe"));
      json.set("config", added.get("config"));
      List<AnnotationState> realms = (List<AnnotationState>)added.get("realms");
      JSON realmsJSON = new JSON();
      if (realms != null) {
        for (AnnotationState sel : realms) {
          ElementHandle.Type clazz = (juzu.impl.compiler.ElementHandle.Type)sel.get("value");
          String name = (String)sel.get("name");
          realmsJSON.set(clazz.getName().toString(), new JSON().set("name", name));
        }
      }
      json.set("realms", realmsJSON);
      enableMap.put(handle, json);
    } else {
      emitConfig(key, added);
    }
  }

  private void emitConfig(AnnotationKey key, AnnotationState added) {
    if (key.getType().equals(Name.create(RequiresGuest.class)) || key.getType().equals(Name.create(RequiresUser.class))
      || key.getType().equals(Name.create(RequiresAuthentication.class))
      || key.getType().equals(Name.create(RequiresRoles.class))
      || key.getType().equals(Name.create(RequiresPermissions.class)) || key.getType().equals(Name.create(Login.class))
      || key.getType().equals(Name.create(Logout.class))) {
      if (key.getElement() instanceof ElementHandle.Method) {
        Map<AnnotationKey, AnnotationState> annotations = methods.get(key.getElement());
        if (annotations == null) {
          annotations = new HashMap<AnnotationKey, AnnotationState>();
          methods.put(key.getElement(), annotations);
        }
        annotations.put(key, added);
      } else if (key.getElement() instanceof ElementHandle.Type) {
        if (key.getType().equals(Name.create(RequiresGuest.class))
          || key.getType().equals(Name.create(RequiresAuthentication.class))
          || key.getType().equals(Name.create(RequiresUser.class))) {
          Map<AnnotationKey, AnnotationState> annotations = controllers.get(key.getElement());
          if (annotations == null) {
            annotations = new HashMap<AnnotationKey, AnnotationState>();
            controllers.put(key.getElement(), annotations);
          }
          annotations.put(key, added);
        } else
          throw new UnsupportedOperationException("Unsupported " + key.getType() + " at " + key.getElement());
      }
    }
  }

  private void emitConfig(JSON json, AnnotationKey key, AnnotationState added) {
    if (key.getType().equals(Name.create(Login.class))) {
      if (json.get("operator") != null) {
        throw new UnsupportedOperationException("Unsupported multiple operators at " + key.getElement());
      }
      json.set("operator", "login");
    } else if (key.getType().equals(Name.create(Logout.class))) {
      if (json.get("operator") != null) {
        throw new UnsupportedOperationException("Unsupported multiple operators at " + key.getElement());
      }
      json.set("operator", "logout");
    } else if (key.getType().equals(Name.create(RequiresGuest.class))) {
      if (json.get("require") != null || json.get("permissions") != null || json.get("roles") != null) {
        throw new UnsupportedOperationException("Unsupported multiple requirements at " + key.getElement());
      }
      json.set("require", "guest");
    } else if (key.getType().equals(Name.create(RequiresUser.class))) {
      if (json.get("require") != null || json.get("permissions") != null || json.get("roles") != null) {
        throw new UnsupportedOperationException("Unsupported multiple requirements at " + key.getElement());
      }
      json.set("require", "user");
    } else if (key.getType().equals(Name.create(RequiresAuthentication.class))) {
      if (json.get("require") != null || json.get("permissions") != null || json.get("roles") != null) {
        throw new UnsupportedOperationException("Unsupported multiple requirements at " + key.getElement());
      }
      json.set("require", "authenticate");
    } else if (key.getType().equals(Name.create(RequiresPermissions.class))) {
      if (json.get("require") != null) {
        throw new UnsupportedOperationException("Unsupported multiple requirements at " + key.getElement());
      }
      ArrayList<String> values = (ArrayList<String>)added.get("value");
      String logical = (String)added.get("logical");
      JSON foo = new JSON();
      foo.set("value", values);
      if (logical != null) {
        foo.set("logical", logical);
      } else {
        foo.set("logical", Logical.AND);
      }
      json.set("permissions", foo);
    } else if (key.getType().equals(Name.create(RequiresRoles.class))) {
      if (json.get("require") != null) {
        throw new UnsupportedOperationException("Unsupported multiple requirements at " + key.getElement());
      }
      ArrayList<String> values = (ArrayList<String>)added.get("value");
      String logical = (String)added.get("logical");
      JSON foo = new JSON();
      foo.set("value", values);
      if (logical != null) {
        foo.set("logical", logical);
      } else {
        foo.set("logical", Logical.AND);
      }
      json.set("roles", foo);
    }
  }

  @Override
  public void postProcessEvents(ApplicationMetaModel metaModel) {
    ElementHandle.Package packageHandle = metaModel.getHandle();
    JSON config = enableMap.get(packageHandle);
    if (config != null) {
      ControllersMetaModel controllersModel = metaModel.getChild(ControllersMetaModel.KEY);

      for (ControllerMetaModel controller : controllersModel) {
        Map<AnnotationKey, AnnotationState> annotations = controllers.get(controller.getHandle());
        if (annotations != null) {
          JSON controllerJSON = new JSON();
          config.set(controller.getHandle().getName().toString(), controllerJSON);

          for (Map.Entry<AnnotationKey, AnnotationState> entry : annotations.entrySet()) {
            AnnotationKey key = entry.getKey();

            if (controllerJSON.get("require") != null) {
              throw new UnsupportedOperationException("Unsupported multiple requirements at " + key.getElement());
            }

            if (key.getType().equals(Name.create(RequiresGuest.class))) {
              controllerJSON.set("require", "guest");
            } else if (key.getType().equals(Name.create(RequiresAuthentication.class))) {
              controllerJSON.set("require", "authenticate");
            } else if (key.getType().equals(Name.create(RequiresUser.class))) {
              controllerJSON.set("require", "user");
            }
          }
        }

        for (HandlerMetaModel handler : controller) {
          annotations = methods.get(handler.getMethod());
          String methodId = handler.getMethod().getMethodHandle().toString();

          if (annotations != null) {
            JSON controllerJSON = config.getJSON(controller.getHandle().getName().toString());
            if (controllerJSON == null) {
              controllerJSON = new JSON();
              config.set(controller.getHandle().getName().toString(), controllerJSON);
            }

            JSON methodJSON = new JSON();;
            for (Map.Entry<AnnotationKey, AnnotationState> entry : annotations.entrySet()) {
              emitConfig(methodJSON, entry.getKey(), entry.getValue());
            }

            JSON methodsJSON = controllerJSON.getJSON("methods");
            if (methodsJSON == null) {
              methodsJSON = new JSON();
              controllerJSON.set("methods", methodsJSON);
            }
            methodsJSON.set(methodId.substring(methodId.lastIndexOf('#') + 1), methodJSON);
          }
        }
      }
    }
  }

  @Override
  public void destroy(ApplicationMetaModel application) {
    enableMap.remove(application.getHandle());
  }

  @Override
  public JSON getDescriptor(ApplicationMetaModel application) {
    return enableMap.get(application.getHandle());
  }
}
TOP

Related Classes of juzu.plugin.shiro.impl.ShiroMetaModelPlugin

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.