Exemple #1
0
/**
 * Resolves template names into URLs.
 *
 * <p>Resolves templates by iterating over all known {@link Resolver} implementations while
 * providing a cache for frequently checked names / URIs.
 */
@Register(classes = Resources.class)
public class Resources {

  /*
   * Logger used by the resource discovery framework
   */
  public static final Log LOG = Log.get("resources");

  @PriorityParts(Resolver.class)
  private Collection<Resolver> resolvers;

  /** Cache used to map a scope name and local uri to an URL pointing to a resolved content. */
  private Cache<String, Optional<Resource>> resolverCache =
      CacheManager.createCache("resolver-cache");

  /**
   * Tries to resolve a template or content-file into a {@link Resource}
   *
   * @param uri the local name of the uri to load
   * @return a {@link Resource} (wrapped as resource) pointing to the requested content or an empty
   *     optional if no resource was found
   */
  @Nonnull
  public Optional<Resource> resolve(@Nonnull String uri) {
    return resolve(UserContext.getCurrentScope().getScopeId(), uri);
  }

  /**
   * Tries to resolve a template or content-file into a {@link Resource}
   *
   * @param scopeId the scope to use. Use {@link #resolve(String)} to pick the currently active
   *     scope
   * @param uri the local name of the uri to load
   * @return a {@link Resource} (wrapped as resource) pointing to the requested content or an empty
   *     optional if no resource was found
   */
  @Nonnull
  public Optional<Resource> resolve(@Nonnull String scopeId, @Nonnull String uri) {
    String lookupKey = scopeId + "://" + uri;
    Optional<Resource> result = resolverCache.get(lookupKey);
    if (result != null) {
      if (Sirius.isDev()) {
        // In dev environments, we always perform a lookup in case something changed
        Optional<Resource> currentResult = resolveURI(scopeId, uri);
        if (!result.isPresent()) {
          return currentResult;
        }
        if (!currentResult.isPresent()
            || !Objects.equals(result.get().getUrl(), currentResult.get().getUrl())) {
          return currentResult;
        }
      }
      return result;
    }
    result = resolveURI(scopeId, uri);
    resolverCache.put(lookupKey, result);
    return result;
  }

  /*
   * Calls all available resolvers to pick the right content for the given scope and uri (without using a cache)
   */
  private Optional<Resource> resolveURI(String scopeId, String uri) {
    if (!uri.startsWith("/")) {
      uri = "/" + uri;
    }
    for (Resolver res : resolvers) {
      Resource r = res.resolve(scopeId, uri);
      if (r != null) {
        return Optional.of(r);
      }
    }
    return Optional.empty();
  }
}
/** Created by aha on 08.05.15. */
public class BizController implements Controller {

  @Part protected OMA oma;

  @Part protected Tenants tenants;

  public static final Log LOG = Log.get("biz");

  protected UserInfo getUser() {
    return UserContext.getCurrentUser();
  }

  protected boolean hasPermission(String permission) {
    return getUser().hasPermission(permission);
  }

  protected void assertPermission(String permission) {}

  protected void assertTenant(TenantAware tenantAware) {}

  protected void assertNotNull(Object obj) {}

  protected void assertNotNew(Object obj) {}

  protected Consumer<WebContext> defaultRoute;

  public BizController() {
    Optional<Method> defaultMethod =
        Arrays.stream(getClass().getDeclaredMethods())
            .filter(m -> m.isAnnotationPresent(DefaultRoute.class))
            .findFirst();
    if (!defaultMethod.isPresent()) {
      throw new IllegalStateException(
          Strings.apply("Controller %s has no default route!", getClass().getName()));
    }
    this.defaultRoute =
        ctx -> {
          try {
            defaultMethod.get().invoke(this, ctx);
          } catch (IllegalAccessException e) {
            throw Exceptions.handle(e);
          } catch (InvocationTargetException e) {
            throw Exceptions.handle(e.getTargetException());
          }
        };
  }

  @Override
  public void onError(WebContext ctx, HandledException error) {
    if (error != null) {
      UserContext.message(Message.error(error.getMessage()));
    }
    defaultRoute.accept(ctx);
  }

  @ConfigValue("product.baseUrl")
  private String baseUrl;

  protected String getBaseUrl() {
    return baseUrl;
  }

  public void showSavedMessage() {
    UserContext.message(Message.info(NLS.get("BizController.changesSaved")));
  }

  public void showDeletedMessage() {
    UserContext.message(Message.info(NLS.get("BizController.objectDeleted")));
  }

  protected void load(WebContext ctx, Entity entity, Column... columns) {
    for (Column c : columns) {
      Property property = entity.getDescriptor().getProperty(c);
      if (property == null) {
        throw new IllegalArgumentException(
            Strings.apply("Unknown property '%s' for type '%s'", c, entity.getClass().getName()));
      }
      property.parseValue(entity, ctx.get(property.getName()));
    }
  }

  protected <E extends BizEntity> E find(Class<E> type, String id) {
    if (BizEntity.NEW.equals(id)) {
      try {
        return type.newInstance();
      } catch (Throwable e) {
        throw Exceptions.handle()
            .to(LOG)
            .error(e)
            .withSystemErrorMessage("Cannot create a new instance of '%s'", type.getName())
            .handle();
      }
    }
    Optional<E> result = oma.find(type, id);
    if (!result.isPresent()) {
      throw Exceptions.createHandled()
          .withNLSKey("BizController.unknownObject")
          .set("id", id)
          .handle();
    }
    return result.get();
  }

  protected <E extends BizEntity> Optional<E> tryFind(Class<E> type, String id) {
    if (BizEntity.NEW.equals(id)) {
      return Optional.empty();
    }
    return oma.find(type, id);
  }

  protected <E extends BizEntity> E findForTenant(Class<E> type, String id) {
    E result = find(type, id);
    if (!result.isNew() && result instanceof TenantAware) {
      assertTenant((TenantAware) result);
    }
    return result;
  }

  protected <E extends BizEntity> Optional<E> tryFindForTenant(Class<E> type, String id) {
    return tryFind(type, id)
        .map(
            e -> {
              if (e instanceof TenantAware) {
                assertTenant((TenantAware) e);
              }
              return e;
            });
  }
}