Package org.structr.schema

Source Code of org.structr.schema.SchemaService

/**
* Copyright (C) 2010-2014 Morgner UG (haftungsbeschränkt)
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Structr.  If not, see <http://www.gnu.org/licenses/>.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package org.structr.schema;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.structr.common.StructrConf;
import org.structr.common.error.ErrorBuffer;
import org.structr.common.error.FrameworkException;
import org.structr.core.Command;
import org.structr.core.Service;
import org.structr.core.app.App;
import org.structr.core.app.StructrApp;
import org.structr.core.entity.SchemaNode;
import org.structr.core.entity.relationship.SchemaRelationship;
import org.structr.core.graph.Tx;
import org.structr.schema.compiler.NodeExtender;

/**
*
* @author Christian Morgner
*/
public class SchemaService implements Service {

  private static final Logger logger                            = Logger.getLogger(SchemaService.class.getName());
  private static final AtomicBoolean compiling                  = new AtomicBoolean(false);
  private static final Map<String, String> builtinTypeMap       = new LinkedHashMap<>();

  @Override
  public void injectArguments(final Command command) {
  }

  @Override
  public void initialize(final StructrConf config) {
    reloadSchema(new ErrorBuffer());
  }

  public static void registerBuiltinTypeOverride(final String type, final String fqcn) {
    builtinTypeMap.put(type, fqcn);
  }

  public static boolean reloadSchema(final ErrorBuffer errorBuffer) {

    final ConfigurationProvider config = StructrApp.getConfiguration();
    boolean success = true;

    // compiling must only be done once
    if (compiling.compareAndSet(false, true)) {

      // this is a very critical section :)
      synchronized (SchemaService.class) {

        final Set<String> dynamicViews  = new LinkedHashSet<>();
        final NodeExtender nodeExtender = new NodeExtender();

        try (final Tx tx = StructrApp.getInstance().tx()) {

          SchemaService.ensureBuiltinTypesExist();

          // collect node classes
          for (final SchemaNode schemaNode : StructrApp.getInstance().nodeQuery(SchemaNode.class).getAsList()) {

            nodeExtender.addClass(schemaNode.getClassName(), schemaNode.getSource(errorBuffer));

            final String auxSource = schemaNode.getAuxiliarySource();
            if (auxSource != null) {

              nodeExtender.addClass("_" + schemaNode.getClassName() + "Helper", auxSource);
            }

            dynamicViews.addAll(schemaNode.getViews());
          }

          // collect relationship classes
          for (final SchemaRelationship schemaRelationship : StructrApp.getInstance().relationshipQuery(SchemaRelationship.class).getAsList()) {

            nodeExtender.addClass(schemaRelationship.getClassName(), schemaRelationship.getSource(errorBuffer));

            final String auxSource = schemaRelationship.getAuxiliarySource();
            if (auxSource != null) {

              nodeExtender.addClass("_" + schemaRelationship.getClassName() + "Helper", auxSource);
            }

            dynamicViews.addAll(schemaRelationship.getViews());
          }

          // compile all classes at once and register
          Map<String, Class> newTypes = nodeExtender.compile(errorBuffer);
          for (final Class newType : newTypes.values()) {

            config.registerEntityType(newType);

            // instantiate classes to execute
            // static initializer of helpers
            try { newType.newInstance(); } catch (Throwable t) {}
          }

          success = !errorBuffer.hasError();

          // inject views in configuration provider
          if (success) {

            config.registerDynamicViews(dynamicViews);
            tx.success();
          }

        } catch (Throwable t) {

          logger.log(Level.SEVERE, "Unable to compile dynamic schema.", t);
          t.printStackTrace();

          success = false;
        }
      }

      // compiling done
      compiling.set(false);
    }

    return success;
  }

  @Override
  public void initialized() {
  }

  @Override
  public void shutdown() {
  }

  @Override
  public String getName() {
    return SchemaService.class.getName();
  }

  @Override
  public boolean isRunning() {
    return true;
  }

  // ----- private methods -----
  public static void ensureBuiltinTypesExist() throws FrameworkException {

    final App app = StructrApp.getInstance();

    for (final Entry<String, String> entry : builtinTypeMap.entrySet()) {

      final String type = entry.getKey();
      final String fqcn = entry.getValue();

      SchemaNode schemaNode = app.nodeQuery(SchemaNode.class).andName(type).getFirst();
      if (schemaNode == null) {

        schemaNode = app.create(SchemaNode.class, type);
      }

      schemaNode.setProperty(SchemaNode.extendsClass, fqcn);
      schemaNode.unlockReadOnlyPropertiesOnce();
      schemaNode.setProperty(SchemaNode.isBuiltinType, true);
    }
  }

  @Override
  public boolean isVital() {
    return true;
  }
}
TOP

Related Classes of org.structr.schema.SchemaService

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.