text:
require "spec_helper"

describe Mongoid::Relations::Macros do

  class TestClass
    include Mongoid::Document
  end

  let(:klass) do
    TestClass
  end

  before do
    klass.relations.clear
    klass._validators.clear
  end

  after do
    klass.relations.clear
    klass.validators.clear
  end

  describe ".embedded_in" do

    it "defines the macro" do
      expect(klass).to respond_to(:embedded_in)
    end

    context 'when the relation name is invalid' do

      let(:relation) do
        klass.embedded_in(:fields)
      end

      it 'raises an InvalidRelation exception' do
        expect {
          relation
        }.to raise_exception(Mongoid::Errors::InvalidRelation)
      end
    end

    context "when defining the relation" do

      before do
        klass.embedded_in(:person)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["person"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:person)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:person=)
      end

      it "creates the correct relation" do
        expect(klass.relations["person"].relation).to eq(
          Mongoid::Relations::Embedded::In
        )
      end

      it "does not add associated validations" do
        expect(klass._validators).to be_empty
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["person"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:person)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end
  end

  describe ".embeds_many" do

    it "defines the macro" do
      expect(klass).to respond_to(:embeds_many)
    end

    context "when defining the relation" do

      context 'when the relation name is invalid' do

        let(:relation) do
          klass.embeds_many(:fields)
        end

        it 'raises an InvalidRelation exception' do
          expect {
            relation
          }.to raise_exception(Mongoid::Errors::InvalidRelation)
        end
      end

      before do
        klass.embeds_many(:addresses)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["addresses"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:addresses)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:addresses=)
      end

      it "creates the correct relation" do
        expect(klass.relations["addresses"].relation).to eq(
          Mongoid::Relations::Embedded::Many
        )
      end

      it "adds an associated validation" do
        expect(klass._validators[:addresses].first).to be_a(
          Mongoid::Validatable::AssociatedValidator
        )
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["addresses"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:addresses)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end

    context 'when defining order on relation' do

      before do
        klass.embeds_many(:addresses, order: :number.asc)
      end

      let(:metadata) do
        klass.relations["addresses"]
      end

      it "adds metadata to klass" do
        expect(metadata.order).to_not be_nil
      end

      it "returns Mongoid::Criteria::Queryable::Key" do
        expect(metadata.order).to be_kind_of(Mongoid::Criteria::Queryable::Key)
      end
    end

    context "when setting validate to false" do

      before do
        klass.embeds_many(:addresses, validate: false)
      end

      it "does not add associated validations" do
        expect(klass._validators).to be_empty
      end
    end
  end

  describe ".embeds_one" do

    it "defines the macro" do
      expect(klass).to respond_to(:embeds_one)
    end

    context "when defining the relation" do

      context 'when the relation name is invalid' do

        let(:relation) do
          klass.embeds_one(:fields)
        end

        it 'raises an InvalidRelation exception' do
          expect {
            relation
          }.to raise_exception(Mongoid::Errors::InvalidRelation)
        end
      end

      before do
        klass.embeds_one(:name)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["name"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:name)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:name=)
      end

      it "defines the builder" do
        expect(klass.allocate).to respond_to(:build_name)
      end

      it "defines the creator" do
        expect(klass.allocate).to respond_to(:create_name)
      end

      it "creates the correct relation" do
        expect(klass.relations["name"].relation).to eq(
          Mongoid::Relations::Embedded::One
        )
      end

      it "adds an associated validation" do
        expect(klass._validators[:name].first).to be_a(
          Mongoid::Validatable::AssociatedValidator
        )
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["name"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:name)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end

    context "when setting validate to false" do

      before do
        klass.embeds_one(:name, validate: false)
      end

      it "does not add associated validations" do
        expect(klass._validators).to be_empty
      end
    end
  end

  describe ".belongs_to" do

    let(:_class) do
      class RelationsTestClass
        include Mongoid::Document
      end
    end

    let(:conf) do
      CONFIG.merge(options: { belongs_to_required_by_default: default_require })
    end

    let(:relation) do
      _class.new
    end

    let(:relation_options) { {} }

    let(:default_require) { Mongoid.belongs_to_required_by_default }

    before do
      Mongoid.configure do |config|
        config.load_configuration(conf)
      end
      _class.belongs_to(:person, relation_options)
    end

    after do
      Object.send(:remove_const, _class.name)
    end

    after(:all) do
      Mongoid.configure do |config|
        config.load_configuration(CONFIG)
      end
    end

    it "defines the macro" do
      expect(_class).to respond_to(:belongs_to)
    end

    context 'when the relation has options' do

      context 'when the relation has the option :required' do

        context 'when the relation does not have the :optional option' do

          context 'when :required is true' do

            let(:relation_options) do
              { required: true }
            end

            context 'when the default config is to require the association' do

              let(:default_require) { true }

              it 'requires the association' do
                expect(relation.save).to be(false)
              end
            end

            context 'when the default config is to not require the association' do

              let(:default_require) { false }

              it 'requires the association' do
                expect(relation.save).to be(false)
              end
            end
          end

          context 'when :required is false' do

            let(:relation_options) do
              { required: false }
            end

            context 'when the default config is to require the association' do

              let(:default_require) { true }

              it 'does not require the association' do
                expect(relation.save).to be(true)
              end
            end

            context 'when the default config is to not require the association' do

              let(:default_require) { false }

              it 'does not require the association' do
                expect(relation.save).to be(true)
              end
            end
          end
        end

        context 'when the relation has the option :optional' do

          context 'when :required is true' do

            context 'when :optional is true' do

              let(:relation_options) do
                {
                  required: true,
                  optional: true
                }
              end

              context 'when the default config is to require the association' do

                let(:default_require) { true }

                it 'requires the association' do
                  expect(relation.save).to be(false)
                end
              end

              context 'when the default config is to not require the association' do

                let(:default_require) { false }

                it 'requires the association' do
                  expect(relation.save).to be(false)
                end
              end
            end

            context 'when :optional is false' do

              let(:relation_options) do
                {
                  required: true,
                  optional: false
                }
              end

              context 'when the default config is to require the association' do

                let(:default_require) { true }

                it 'requires the association' do
                  expect(relation.save).to be(false)
                end
              end

              context 'when the default config is to not require the association' do

                let(:default_require) { false }

                it 'requires the association' do
                  expect(relation.save).to be(false)
                end
              end
            end
          end

          context 'when :required is false' do

            context 'when :optional is true' do

              let(:relation_options) do
                {
                  required: false,
                  optional: true
                }
              end

              context 'when the default config is to require the association' do

                let(:default_require) { true }

                it 'does not require the association' do
                  expect(relation.save).to be(true)
                end
              end

              context 'when the default config is to not require the association' do

                let(:default_require) { true }

                it 'does not require the association' do
                  expect(relation.save).to be(true)
                end
              end
            end

            context 'when :optional is false' do

              let(:relation_options) do
                {
                  required: false,
                  optional: false
                }
              end

              context 'when the default config is to require the association' do

                let(:default_require) { true }

                it 'does not require the association' do
                  expect(relation.save).to be(true)
                end
              end

              context 'when the default config is to not require the association' do

                let(:default_require) { false }

                it 'does not require the association' do
                  expect(relation.save).to be(true)
                end
              end
            end
          end
        end
      end

      context 'when the relation does not have the option :required' do

        context 'when the relation has the option :optional' do

          context 'when :optional is true' do

            let(:relation_options) do
              { optional: true }
            end

            context 'when the default config is to require the association' do

              let(:default_require) { true }

              it 'does not require the association' do
                expect(relation.save).to be(true)
              end
            end

            context 'when the default config is to not require the association' do

              let(:default_require) { false }

              it 'does not require the association' do
                expect(relation.save).to be(true)
              end
            end
          end

          context 'when :optional is false' do

            let(:relation_options) do
              { optional: false }
            end

            context 'when the default config is to require the association' do

              let(:default_require) { true }

              it 'requires the association' do
                expect(relation.save).to be(false)
              end
            end

            context 'when the default config is to not require the association' do

              let(:default_require) { false }

              it 'requires the association' do
                expect(relation.save).to be(false)
              end
            end
          end
        end
      end
    end

    context 'when the relation does not have options' do

      context 'when the default config is to require the association' do

        let(:default_require) { true }

        it 'requires the association' do
          expect(relation.save).to be(false)
        end
      end

      context 'when the default config is to not require the association' do

        let(:default_require) { false }

        it 'does not require the association' do
          expect(relation.save).to be(true)
        end
      end
    end

    context "when the relation is polymorphic" do

      context "when indexed is true" do

        before do
          klass.belongs_to(:relatable, polymorphic: true, index: true)
        end

        let(:index) do
          klass.index_specifications.first
        end

        it "adds the background index to the definitions" do
          expect(index.key).to eq(relatable_id: 1, relatable_type: 1)
        end
      end
    end

    context "when defining the relation" do

      context 'when the relation name is invalid' do

        let(:relation) do
          klass.belongs_to(:fields)
        end

        it 'raises an InvalidRelation exception' do
          expect {
            relation
          }.to raise_exception(Mongoid::Errors::InvalidRelation)
        end
      end

      before do
        klass.belongs_to(:person)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["person"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:person)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:person=)
      end

      it "defines the builder" do
        expect(klass.allocate).to respond_to(:build_person)
      end

      it "defines the creator" do
        expect(klass.allocate).to respond_to(:create_person)
      end

      it "creates the correct relation" do
        expect(klass.relations["person"].relation).to eq(
          Mongoid::Relations::Referenced::In
        )
      end

      it "creates the field for the foreign key" do
        expect(klass.allocate).to respond_to(:person_id)
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["person"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:person)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end
  end

  describe ".has_many" do

    it "defines the macro" do
      expect(klass).to respond_to(:has_many)
    end

    context "when defining the relation" do

      context 'when the relation name is invalid' do

        let(:relation) do
          klass.has_many(:fields)
        end

        it 'raises an InvalidRelation exception' do
          expect {
            relation
          }.to raise_exception(Mongoid::Errors::InvalidRelation)
        end
      end

      before do
        klass.has_many(:posts)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["posts"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:posts)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:posts=)
      end

      it "creates the correct relation" do
        expect(klass.relations["posts"].relation).to eq(
          Mongoid::Relations::Referenced::Many
        )
      end

      it "adds an associated validation" do
        expect(klass._validators[:posts].first).to be_a(
          Mongoid::Validatable::AssociatedValidator
        )
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["posts"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:posts)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end

    context 'when defining order on relation' do

      before do
        klass.has_many(:posts, order: :rating.asc)
      end

      let(:metadata) do
        klass.relations["posts"]
      end

      it "adds metadata to klass" do
        expect(metadata.order).to_not be_nil
      end

      it "returns Mongoid::Criteria::Queryable::Key" do
        expect(metadata.order).to be_kind_of(Mongoid::Criteria::Queryable::Key)
      end
    end

    context "when setting validate to false" do

      before do
        klass.has_many(:posts, validate: false)
      end

      it "does not add associated validations" do
        expect(klass._validators).to be_empty
      end
    end
  end

  describe ".has_and_belongs_to_many" do

    it "defines the macro" do
      expect(klass).to respond_to(:has_and_belongs_to_many)
    end

    context "when defining the relation" do

      context 'when the relation name is invalid' do

        let(:relation) do
          klass.has_and_belongs_to_many(:fields)
        end

        it 'raises an InvalidRelation exception' do
          expect {
            relation
          }.to raise_exception(Mongoid::Errors::InvalidRelation)
        end
      end

      before do
        klass.has_and_belongs_to_many(:preferences)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["preferences"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:preferences)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:preferences=)
      end

      it "creates the correct relation" do
        expect(klass.relations["preferences"].relation).to eq(
          Mongoid::Relations::Referenced::ManyToMany
        )
      end

      it "creates the field for the foreign key" do
        expect(klass.allocate).to respond_to(:preference_ids)
      end

      context 'when defining order on relation' do

        before do
          klass.has_and_belongs_to_many(:preferences, order: :ranking.asc)
        end

        let(:metadata) do
          klass.relations["preferences"]
        end

        it "adds metadata to klass" do
          expect(metadata.order).to_not be_nil
        end

        it "returns Mongoid::Criteria::Queryable::Key" do
          expect(metadata.order).to be_kind_of(Mongoid::Criteria::Queryable::Key)
        end
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["preferences"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:preferences)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end
  end

  describe ".has_one" do

    it "defines the macro" do
      expect(klass).to respond_to(:has_one)
    end

    context "when defining the relation" do

      context 'when the relation name is invalid' do

        let(:relation) do
          klass.has_one(:fields)
        end

        it 'raises an InvalidRelation exception' do
          expect {
            relation
          }.to raise_exception(Mongoid::Errors::InvalidRelation)
        end
      end

      before do
        klass.has_one(:game)
      end

      it "adds the metadata to the klass" do
        expect(klass.relations["game"]).to_not be_nil
      end

      it "defines the getter" do
        expect(klass.allocate).to respond_to(:game)
      end

      it "defines the setter" do
        expect(klass.allocate).to respond_to(:game=)
      end

      it "defines the builder" do
        expect(klass.allocate).to respond_to(:build_game)
      end

      it "defines the creator" do
        expect(klass.allocate).to respond_to(:create_game)
      end

      it "creates the correct relation" do
        expect(klass.relations["game"].relation).to eq(
          Mongoid::Relations::Referenced::One
        )
      end

      it "adds an associated validation" do
        expect(klass._validators[:game].first).to be_a(
          Mongoid::Validatable::AssociatedValidator
        )
      end

      context "metadata properties" do

        let(:metadata) do
          klass.relations["game"]
        end

        it "automatically adds the name" do
          expect(metadata.name).to eq(:game)
        end

        it "automatically adds the inverse class name" do
          expect(metadata.inverse_class_name).to eq("TestClass")
        end
      end
    end

    context "when setting validate to false" do

      before do
        klass.has_one(:game, validate: false)
      end

      it "does not add associated validations" do
        expect(klass._validators).to be_empty
      end
    end
  end

  describe "#relations" do

    before do
      klass.embeds_one(:name)
    end

    it "returns a hash of relations" do
      expect(klass.allocate.relations).to be_a_kind_of(Hash)
    end

    it "has keys that are the relation name" do
      expect(klass.allocate.relations.keys.first).to eq("name")
    end

    it "has values that are metadata" do
      expect(
        klass.allocate.relations.values.first
      ).to be_a_kind_of(Mongoid::Relations::Metadata)
    end
  end

  describe ".relations" do

    before do
      klass.embeds_one(:name)
    end

    it "returns a hash of relations" do
      expect(klass.relations).to be_a_kind_of(Hash)
    end

    it "has keys that are the relation name" do
      expect(klass.relations.keys.first).to eq("name")
    end

    it "has values that are metadata" do
      expect(
        klass.relations.values.first
      ).to be_a_kind_of(Mongoid::Relations::Metadata)
    end
  end

  context "when creating an association with an extension" do

    class Peep
      include Mongoid::Document
    end

    class Handle
      include Mongoid::Document

      module Extension
        def short_name
          "spec"
        end
      end

      module AnotherExtension
        def very_short_name
          "spec"
        end
      end
    end

    let(:peep) do
      Peep.new(handle: Handle.new)
    end

    context "when the extension is a block" do

      before do
        Peep.embeds_one(:handle) do
          def full_name
            "spec"
          end
        end
      end

      it "extends the relation" do
        expect(peep.handle.full_name).to eq("spec")
      end
    end

    context "when the extension is a module" do

      before do
        Peep.embeds_one(:handle, extend: Handle::Extension)
      end

      it "extends the relation" do
        expect(peep.handle.short_name).to eq("spec")
      end
    end

    context "when the extension is two modules" do

      before do
        Peep.embeds_one(:handle, extend: [ Handle::Extension, Handle::AnotherExtension ])
      end

      it "extends the relation" do
        expect(peep.handle.very_short_name).to eq("spec")
      end
    end
  end
end


text:
"""
===============================================================================

    Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).

    This file is part of cardinal_pythonlib.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        https://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

===============================================================================

**Functions to work with SQLAlchemy sessions/engines.**

"""

from typing import TYPE_CHECKING
import os

from sqlalchemy.engine import create_engine
from sqlalchemy.engine.base import Engine
from sqlalchemy.engine.url import make_url
from sqlalchemy.orm.session import Session

from cardinal_pythonlib.logs import get_brace_style_log_with_null_handler

if TYPE_CHECKING:
    from sqlalchemy.engine.url import URL

log = get_brace_style_log_with_null_handler(__name__)

# =============================================================================
# Database URLs
# =============================================================================

SQLITE_MEMORY_URL = "sqlite://"

def make_mysql_url(
    username: str,
    password: str,
    dbname: str,
    driver: str = "mysqldb",
    host: str = "localhost",
    port: int = 3306,
    charset: str = "utf8",
) -> str:
    """
    Makes an SQLAlchemy URL for a MySQL database.
    """
    return "mysql+{driver}://{u}:{p}@{host}:{port}/{db}?charset={cs}".format(
        driver=driver,
        host=host,
        port=port,
        db=dbname,
        u=username,
        p=password,
        cs=charset,
    )

def make_sqlite_url(filename: str) -> str:
    """
    Makes an SQLAlchemy URL for a SQLite database.
    """
    absfile = os.path.abspath(filename)
    return "sqlite://{host}/{path}".format(host="", path=absfile)
    # ... makes it clear how it works! Ends up being sqlite:////abspath
    # or sqlite:///relpath. Also works with backslashes for Windows paths; see
    # http://docs.sqlalchemy.org/en/latest/core/engines.html#sqlite

# =============================================================================
# Connection management
# =============================================================================

def get_engine_from_session(dbsession: Session) -> Engine:
    """
    Gets the SQLAlchemy :class:`Engine` from a SQLAlchemy :class:`Session`.
    """
    engine = dbsession.bind
    assert isinstance(engine, Engine)
    return engine

def get_safe_url_from_engine(engine: Engine) -> str:
    """
    Gets a URL from an :class:`Engine`, obscuring the password.
    """
    raw_url = engine.url  # type: str
    url_obj = make_url(raw_url)  # type: URL
    return repr(url_obj)
    # The default repr() implementation calls
    # self.__to_string__(hide_password=False)

def get_safe_url_from_session(dbsession: Session) -> str:
    """
    Gets a URL from a :class:`Session`, obscuring the password.
    """
    return get_safe_url_from_engine(get_engine_from_session(dbsession))

def get_safe_url_from_url(url: str) -> str:
    """
    Converts an SQLAlchemy URL into a safe version that obscures the password.
    """
    engine = create_engine(url)
    return get_safe_url_from_engine(engine)

redpajama_set_name: RedPajamaGithub


text:
package org.batgen.generators;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.List;

import org.batgen.DatabaseType;

public class MybatisConfigGenerator {

    private StringBuilder sb;

    /**
     * Basic resources stored as string to be used in the program.
     */
    private String packagePath;
    private String fileNameWithPath = "src/main/resources/";
    private String fileType = ".xml";
    private List<String> classNames;

    private static final String TAB = "    ";

    /**
     * Sets the default environment to be written into the mybatis-config.xml
     * file
     */
    private String defaultEnvironment;

    /**
     * @param classNames
     *            - list of all class names from the .txt files under settings
     * @param packagePath
     *            - this must be the String result of a "table.getPackagePath()"
     *            call
     */
    public MybatisConfigGenerator( List<String> classNames, String packagePath,
            DatabaseType databaseType ) {

        this.packagePath = packagePath;
        this.classNames = classNames;
        this.defaultEnvironment = databaseType.toString();
        fileNameWithPath += packagePath + "/dao/mybatis-config.xml";
        fileNameWithPath = fileNameWithPath.replace( ".", "/" );
        char[] path = fileNameWithPath.toCharArray();
        path[path.length - 4] = '.';
        fileNameWithPath = new String( path );
    }

    /**
     * This method calls the other methods within this class as necessary to
     * create the text of the mybatis-configuration file, which it then writes
     * to file.
     */
    public String createConfiguration() {
        sb = new StringBuilder();

        createHeader();
        createEnvironments();
        createMappers();
        sb.append( createFooter() );
        writeToFile( sb.toString() );

        return fileNameWithPath;

    }

    /**
     * This method iterates through the sample environment information as
     * defined in the String[] constants. The result is a collection of
     * "environment" elements in the mybatis-config.xml file that can be useful
     * samples, or ready to be used in a production environment with minimal
     * changes made to the output file. This method adds in descriptions of what
     * each element is to aid the user in knowing what values to put where.
     */
    private void createEnvironments() {

        sb.append( TAB + "<environments default=\"" + defaultEnvironment
                + "\">\n\n" );

        DatabaseEnvironment samples = DatabaseEnvironment.createH2Environment();
        sb.append( samples.createEnvironment() + "\n" );

        samples = DatabaseEnvironment.createOracleEnvironment();
        sb.append( samples.createEnvironment() + "\n" );

        samples = DatabaseEnvironment
                .createTestEnvironment( defaultEnvironment );
        sb.append( samples.createEnvironment() + "\n" );

        sb.append( samples.createJNDIEnvironment() + "\n" );

        sb.append( TAB + "</environments>\n\n" );

    }

    /**
     * @return - returns the full set of mappers that this file will contain
     */
    private String createMappers() {

        sb.append( TAB + "<mappers>\n" );

        for ( String name : classNames ) {
            sb.append( TAB + TAB + "<mapper resource=\"" + getMapperPath()
                    + "/dao/" + name + "Dao" + fileType + "\" />\n" );
        }
        sb.append( TAB + "</mappers>\n\n" );

        return sb.toString();
    }

    /**
     * This method returns the path for this table as it is for the resulting
     * package. This methods contents were copied and pasted from
     * SessionFactoryGenerator's method "getPackagePath()", which was
     * unreachable as it is declared private
     *
     * @param filePath
     *            - this is the path where the .txt config file is being stored
     * @return filepath for this mapper, e.g.
     *         "com/simoncomputing/sample/xml/Employee"
     */
    private String getMapperPath() {

        packagePath = packagePath.replace( ".", "/" );
        return packagePath;

    }

    /**
     *
     * @return - creates the standard xml header for this file, and appends the
     *         first element for the file, "configuration"
     */
    private String createHeader() {

        sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" );
        sb.append( "<!DOCTYPE configuration\n" );
        sb.append( TAB
                + "PUBLIC \"-//mybatis.org//DTD Config 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-config.dtd\">\n" );
        sb.append( "<configuration>\n\n" );

        return sb.toString();

    }

    /**
     *
     * @return - simply returns closing part of the "configuration" element that
     *         was appended in the header
     */
    private String createFooter() {

        return "</configuration>";

    }

    /**
     * This method was copied and pasted from Generator.java. This was done to
     * prevent the need for a method for passing in the "String[] files", so
     * that that String[] could simply be passed in via the constructor. By
     * doing that, this method was the *only* one needed from Generator.
     * Therefore, the code was copied over to decrease the coupling between this
     * generator and its cousins. (However it has been modified slightly)
     *
     * @param content
     *            - String to be written to the file
     */
    public void writeToFile( String content ) {
        File file = new File( fileNameWithPath );
        file = new File( file.getParent() );

        if ( file.exists() == false ) {
            file.mkdirs();
        }
        try {

            PrintWriter pw = new PrintWriter( fileNameWithPath );
            pw.write( content );
            pw.close();

        } catch ( FileNotFoundException e ) {
            e.printStackTrace();
        }
    }

}


text:
FROM ubuntu:xenial

# Install node.js and other dependencies and create node user
RUN apt-get update && \
    apt-get -y install curl git graphicsmagick && \
    curl -sL https://deb.nodesource.com/setup_6.x | bash - && \
    apt-get -y install python build-essential nodejs && \
    npm install -g nodemon gulp node-sass critical gulp-util && \
    useradd -c 'node user' -m -d /home/node -s /bin/bash node && \
    chown -R node:node /home/node

# Change to the node user (prevents volume share issues)
USER node

# Define working directory
ENV HOME /home/node
WORKDIR /home/node

# Expose port
EXPOSE  3000

# Run script
CMD ["/bin/bash", "/home/node/run.sh"]


text:
layout: post
date: '2016-08-25'
title: "One Shoulder Single Shoulder Long Bridesmaids Dress 1295"
category: One Shoulder
tags: [One Shoulder]
---
### One Shoulder Single Shoulder Long Bridesmaids Dress 1295
Just **$213.99**
###

Buy it: [https://www.eudances.com/en/one-shoulder/2100-single-shoulder-long-bridesmaids-dress-1295.html](https://www.eudances.com/en/one-shoulder/2100-single-shoulder-long-bridesmaids-dress-1295.html)


text:
require 'rails_helper'

feature 'Programs page' do
  context 'when not signed in' do
    before :each do
      visit '/admin/programs'
    end

    it 'redirects to the admin sign in page' do
      expect(current_path).to eq(new_admin_session_path)
    end

    it 'prompts the user to sign in or sign up' do
      expect(page).
        to have_content 'You need to sign in or sign up before continuing.'
    end

    it 'does not include a link to programs in the navigation' do
      within '.navbar' do
        expect(page).not_to have_link I18n.t('admin.buttons.programs'), href: admin_programs_path
      end
    end
  end

  context 'when signed in' do
    before :each do
      login_admin
      visit '/admin/programs'
    end

    it 'displays instructions for editing programs' do
      expect(page).to have_content 'Below you should see a list of programs'
      expect(page).to have_content 'To start updating, click on one of the links'
      expect(page).not_to have_content 'As a super admin'
    end

    it 'only shows links that belong to the admin' do
      nearby = create(:nearby_loc)
      nearby.organization.programs.
        create!(attributes_for(:program).merge(name: 'Nearby Program'))

      loc = create(:location_for_org_admin)
      loc.organization.programs.create!(attributes_for(:program))

      visit '/admin/programs'
      expect(page).not_to have_link 'Nearby Program'
      expect(page).to have_link 'Collection of Services'
    end

    it 'does not show add new program button if admin has no organizations' do
      create(:nearby_loc)
      visit '/admin/programs'

      expect(page).not_to have_content I18n.t('admin.buttons.add_program')
    end

    it 'shows add new program button if admin has an organization' do
      create(:location_for_org_admin)
      visit '/admin/programs'

      expect(page).to have_link I18n.t('admin.buttons.add_program')
    end
  end

  context 'when signed in as super admin' do
    before :each do
      nearby = create(:nearby_loc)
      @program = nearby.organization.programs.
                 create!(attributes_for(:program).
                 merge(name: 'Nearby Program'))

      loc = create(:location_for_org_admin)
      loc.organization.programs.create!(attributes_for(:program))

      login_super_admin
      visit '/admin/programs'
    end

    it 'displays instructions for editing programs' do
      expect(page).to have_content 'As a super admin'
    end

    it 'shows all programs' do
      expect(page).to have_link 'Nearby Program'
      expect(page).to have_link 'Collection of Services'
    end

    it 'takes you to the right program when clicked' do
      click_link 'Nearby Program'
      expect(current_path).to eq edit_admin_program_path(@program)
    end

    it 'sorts programs alphabetically by name' do
      expect(page.all('a')[9][:href]).
        to eq "/admin/programs/#{@program.id}/edit"
    end

    it 'shows the add new program button' do
      expect(page).to have_link I18n.t('admin.buttons.add_program')
    end
  end
end


text:
#include "gb-include.h"

#include "Pages.h"
#include "Collectiondb.h"
#include "Msg4.h"
#include "Spider.h"
#include "Parms.h"

static bool sendReply        ( void *state  , bool addUrlEnabled );

//static void addedStuff ( void *state );

// class State1 {
// public:
// 	Msg4       m_msg4;
// 	//TcpSocket *m_socket;
// 	//HttpRequest m_hr;
// 	//int32_t       m_urlLen;
// 	//char       m_url[MAX_URL_LEN];
// 	//bool       m_strip;
// 	//bool       m_spiderLinks;
// 	int32_t       m_numSent;
// 	int32_t       m_numReceived;
// 	SpiderRequest m_sreq;
// };

// from PageCrawlBot.cpp:
bool getSpiderRequestMetaList ( char *doc ,
				SafeBuf *listBuf ,
				bool spiderLinks ,
				CollectionRec *cr ) ;

static void addedUrlsToSpiderdbWrapper ( void *state ) {
	//gr *st1 = (gr *)state;
	// otherwise call gotResults which returns false if blocked, true else
	// and sets g_errno on error
	sendReply ( state , true );
}

// . returns false if blocked, true otherwise
// . sets g_errno on error
// . add url page for admin, users use sendPageAddUrl() in PageRoot.cpp
bool sendPageAddUrl2 ( TcpSocket *sock , HttpRequest *hr ) {

	// or if in read-only mode
	if ( g_conf.m_readOnlyMode ) {
		g_errno = EREADONLYMODE;
		char *msg = mstrerror(g_errno);
		return g_httpServer.sendErrorReply(sock,500,msg);
	}

	// . get fields from cgi field of the requested url
	// . get the search query
	int32_t  urlLen = 0;
	char *urls = hr->getString ( "urls" , &urlLen , NULL /*default*/);
	// also try "url" and "urls"
	//if ( ! url ) url = r->getString ( "url" , &urlLen , NULL );
	//if ( ! url ) url = r->getString ( "urls" , &urlLen , NULL );

	char format = hr->getReplyFormat();

	char *c = hr->getString("c");

	if ( ! c && (format == FORMAT_XML || format == FORMAT_JSON) ) {
		g_errno = EMISSINGINPUT;
		char *msg = "missing c parm. See /admin/api to see parms.";
		return g_httpServer.sendErrorReply(sock,500,msg);
	}

	if ( ! urls && (format == FORMAT_XML || format == FORMAT_JSON) ) {
		g_errno = EMISSINGINPUT;
		char *msg = "missing urls parm. See /admin/api to see parms.";
		return g_httpServer.sendErrorReply(sock,500,msg);
	}

	// get collection rec
	CollectionRec *cr = g_collectiondb.getRec ( hr );
	// bitch if no collection rec found
	if ( ! cr ) {
		g_errno = ENOCOLLREC;
		//g_msg = " (error: no collection)";
		char *msg = mstrerror(g_errno);
		return g_httpServer.sendErrorReply(sock,500,msg);
	}

	// make a new state
	GigablastRequest *gr;
	try { gr = new (GigablastRequest); }
	catch ( ... ) {
		g_errno = ENOMEM;
		log("PageAddUrl: new(%i): %s",
		    (int)sizeof(GigablastRequest),mstrerror(g_errno));
		return g_httpServer.sendErrorReply(sock,500,
						   mstrerror(g_errno));
	}
	mnew ( gr , sizeof(GigablastRequest) , "PageAddUrl" );

	// this will fill in GigablastRequest so all the parms we need are set
	// set this. also sets gr->m_hr
	g_parms.setGigablastRequest ( sock , hr , gr );

	// if no url given, just print a blank page
	if ( ! urls ) return sendReply (  gr , true );

	bool status = true;

	// do not spider links for spots
	if ( ! getSpiderRequestMetaList ( urls,
					  // a safebuf
					  &gr->m_listBuf ,
					  gr->m_harvestLinks, // spiderLinks?
					  NULL ) )
		status = false;

	// empty?
	int32_t size = gr->m_listBuf.length();

	// error?
	if ( ! status ) {
		// nuke it
		mdelete ( gr , sizeof(gr) , "PageAddUrl" );
		delete (gr);
		return g_httpServer.sendErrorReply(gr);
	}
	// if not list
	if ( ! size ) {
		// nuke it
		mdelete ( gr , sizeof(gr) , "PageAddUrl" );
		delete (gr);
		g_errno = EMISSINGINPUT;
		return g_httpServer.sendErrorReply(gr);
	}

	// add to spiderdb
	if ( ! gr->m_msg4.addMetaList( gr->m_listBuf.getBufStart() ,
				       gr->m_listBuf.length(),
				       cr->m_coll,
				       gr ,
				       addedUrlsToSpiderdbWrapper,
				       0 // niceness
				       ) )
		// blocked!
		return false;

	// did not block, print page!
	//addedUrlsToSpiderdbWrapper(gr);
	sendReply ( gr , true );
	return true;

	// send back the reply
	//return sendReply ( gr , true );
}

bool sendReply ( void *state , bool addUrlEnabled ) {
	// allow others to add now
	//s_inprogress = false;
	// get the state properly
	//gr *st1 = (gr *) state;
	GigablastRequest *gr = (GigablastRequest *)state;
	// in order to see what sites are being added log it, then we can
	// more easily remove sites from sitesearch.gigablast.com that are
	// being added but not being searched
	SafeBuf xb;
	if ( gr->m_urlsBuf ) {
		xb.safeTruncateEllipsis ( gr->m_urlsBuf , 200 );
		log(LOG_INFO,"http: add url %s (%s)",
		    xb.getBufStart(),mstrerror(g_errno));
	}

	char format = gr->m_hr.getReplyFormat();
	TcpSocket *sock    = gr->m_socket;

	if ( format == FORMAT_JSON || format == FORMAT_XML ) {
		bool status = g_httpServer.sendSuccessReply ( gr );
		// nuke state
		mdelete ( gr , sizeof(gr) , "PageAddUrl" );
		delete (gr);
		return status;
	}

	int32_t ulen = 0;
	char *url = gr->m_urlsBuf;
	if ( url ) ulen = gbstrlen (url);

	// re-null it out if just http://
	bool printUrl = true;
	if ( ulen == 0 ) printUrl = false;
	if ( ! gr->m_urlsBuf       ) printUrl = false;
	if ( ulen==7 && printUrl && !strncasecmp(gr->m_url,"http://",7))
		printUrl = false;
	if ( ulen==8 && printUrl && !strncasecmp(gr->m_url,"https://",8))
		printUrl = false;

	// page is not more than 32k
	char buf[1024*32+MAX_URL_LEN*2];
	SafeBuf sb(buf, 1024*32+MAX_URL_LEN*2);

	//char rawbuf[1024*8];
	//SafeBuf rb(rawbuf, 1024*8);
	//rb.safePrintf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
	//rb.safePrintf("<status>\n");
	//CollectionRec *cr = g_collectiondb.getRec ( gr->m_coll );

	// collection name

	char tt [ 128 ];
	tt[0] = '\0';

	g_pages.printAdminTop ( &sb , sock , &gr->m_hr );

	// display url
	//char *url = gr->m_urlsBuf;
	//if ( url && ! url[0] ) url = NULL;

	// watch out for NULLs
	if ( ! url ) url = "http://";

	// if there was an error let them know
	//char msg[MAX_URL_LEN + 1024];
	SafeBuf mbuf;
	//char *pm = "";
	if ( g_errno ) {
		mbuf.safePrintf("");
		mbuf.safePrintf("Error adding url(s): %s[%i]",
				mstrerror(g_errno) , g_errno);
		mbuf.safePrintf("");
		//pm = msg;
		//rb.safePrintf("Error adding url(s): %s[%i]",
		//	      mstrerror(g_errno) , g_errno);
	}
	else if ( printUrl ) {
		mbuf.safePrintf("");
		mbuf.safePrintf("");
		mbuf.safeTruncateEllipsis(gr->m_urlsBuf,200);
		mbuf.safePrintf(" added to spider "
				 "queue "
				 "successfully

");
		mbuf.safePrintf("");
		//rb.safePrintf("%s added to spider "
		//	      "queue successfully", url );
		//pm = msg;
		//url = "http://";
		//else
		//	pm = "Don't forget to "
		//		"Gigaboost your URL.";
	}

	if ( mbuf.length() ) sb.safeStrcpy ( mbuf.getBufStart() );

	g_parms.printParmTable ( &sb , sock , &gr->m_hr );

	// print the final tail
	g_pages.printTail ( &sb, true ); // admin?
	// clear g_errno, if any, so our reply send goes through
	g_errno = 0;

	// nuke state
	mdelete ( gr , sizeof(GigablastRequest) , "PageAddUrl" );
	delete (gr);

	return g_httpServer.sendDynamicPage (sock,
					     sb.getBufStart(),
					     sb.length(),
					     -1 ); // cachetime
}


text:
package hmi.graphics.scenegraph;

import hmi.animation.VJoint;
import hmi.math.Mat3f;
import hmi.math.Quat4f;
import hmi.math.Vec3f;
import hmi.util.BinUtil;
import hmi.util.BinaryExternalizable;
import hmi.util.Diff;
import hmi.xml.XMLFormatting;
import hmi.xml.XMLStructureAdapter;
import hmi.xml.XMLTokenizer;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * GNode represent a scenegraph node, that contains GNode typed children,
 * references GShapes, and specifies a local 3D transformation.
 * The latter is specified by either a 4X4 matrix, and/or by the following:
 *

 *
 A translation vector, defined by a Vec3f float array

 *
 A rotation quaternion , defined by a Quat4f float array

 *
 A scaling, defined by either a scale vector (a Vec3f array) or a scaling matrix (a Mat3f array)

 *

 * It is allowed to set either the matrix, or the rotation/translation/scaling attributes,
 * then ask for any of them; automatic conversion between these two alternatives is performed.
 * @author Job Zwiers
 */
public class GNode extends XMLStructureAdapter implements BinaryExternalizable, Diff.Differentiable {

   private String id;       // (optionally) id, supposed to be a "globally" unique identifier within the scenegraph
   private String sid;      // (optionally) Scoped id: unique amongs siblings in the scene graph, not necesarily globally unique
   private String name;     // (optionally) Friendly name, without constraints.
   private String type;     //  (optionally) node type, like "JOINT" or "NODE"
   private GNode parent;               // parent node in the scene graph, possibly null
   private List<GNode> gnodes;         // list of child nodes in the scene graph
   private List<GShape> gshapes;       // list of gshapes, containing geometry and materials
   private VJoint joint = new VJoint(); // a link to a VJoint that determines the rotation, translation, and scaling for this GNode.

   private static final List<GNode> EMPTYGNODELIST = new ArrayList<GNode>(0);
   private static final List<GShape> EMPTYGSHAPELIST = new ArrayList<GShape>(0);

   private float[] vec = Vec3f.getVec3f(); // Vec3f for intermediate calculations.
   private static Logger logger = LoggerFactory.getLogger(GNode.class.getName());

   /**
    * GNode.Predicates are Objects that implement a boolean test on GNodes,
    * in the form of their "valid" method. If some GNode vo satifies
    * some predicate pred, then pred.valid(vo) should yield "true".
    */
   public interface Predicate {
      boolean valid(GNode obj);
   }

   /**
    * Creates a new GNode with null id.
    */
   public GNode() {
   }

   /**
    * Creates a new GNode with specified id.
    */
   public GNode(String id) {
      this();
      setId(id);
   }

   public GNode(XMLTokenizer tokenizer) throws IOException {
       this();
       readXML(tokenizer);
   }

   /**
    * show differences
    */
   public String showDiff(Object gnodeObj) {
      GNode gnode = (GNode) gnodeObj;
      if (gnode==null) return "GNode " + id + ", diff: null GNode";
      String diff = Diff.showDiff("GNode, id", id, gnode.id);
      if (diff != "") return diff;
      diff = Diff.showDiff("GNode " + id + ", diff sid", sid, gnode.sid);
      if (diff != "") return diff;
      diff = Diff.showDiff("GNode " + id + ", diff name", name, gnode.name);
      if (diff != "") return diff;
      diff = Diff.showDiff("GNode " + id + ", diff type", type, gnode.type);
      if (diff != "") return diff;
      String parId1 = parent == null ? null : parent.getId();
      String parId2 = gnode.parent == null ? null : gnode.parent.getId();
      diff = Diff.showDiff("GNode " + id + ", diff parent", parId1, parId2);
      if (diff != "") return diff;
      diff = Diff.showDiff("GNode " + id + ", diff gshapes", gshapes, gnode.gshapes);
      if (diff != "") return diff;
      diff = Diff.showDiff("GNode " + id + ", diff child nodes", gnodes, gnode.gnodes); // recursive showDiff
      if (diff != "") return diff;
      diff = joint.showLocalDiff("GNode " + id + ", diff VJoints ", gnode.joint);
      if (diff != "") return diff;
      return "";
   }

   /**
    * Sets the id attribute.
    */
   public void setId(String id) {  this.id = (id==null) ? null : id.intern();  joint.setId(id); }

   /**
    * Returns the id attribute.
    */
   public String getId() {  return id;  }

   /**
    * Sets the Collada sid attribute.
    */
   public void setSid(String sid) { this.sid = (sid==null) ? null : sid.intern(); joint.setSid(sid);  }

   /**
    * Returns the Collada sid attribute.
    */
   public String getSid() {  return sid; }

   /**
    * Sets the name attribute.
    */
   public void setName(String name) { this.name = (name==null) ? null : name.intern(); joint.setName(name);  }

   /**
    * Returns the name attribute.
    */
   public String getName() {  return name; }

   /**
    * Sets the Collada type attribute.
    */
   public void setType(String type) { this.type = (type==null) ? null : type.intern();   }

   /**
    * Returns the Collada type attribute.
    */
   public String getType() {  return type; }

   /**
    * Selects recursively all offspring
    */
   public List<GNode> selectGNodes() {
      return selectGNodes(null, null);
   }

   /**
    * Selects recursively all child GNodes that satisfy the predicate
    */
   public List<GNode> selectGNodes(Predicate select) {
      return selectGNodes(select, null);
   }

   /**
    * Selects recursively child GNodes that satisfy the predicate.
    * The recursive search is pruned for GNodes that satisfy the prune predicate
    */
   public List<GNode> selectGNodes(Predicate select, Predicate prune) {
      return selectGNodes(select, prune, new ArrayList<GNode>());
   }

   /**
    * Selects recursively child GNodes that satisfy the predicate.
    * The recursive search is pruned for GNodes that satisfy the prune predicate.
    * The results are added to the specified List.
    */
   public List<GNode> selectGNodes(Predicate select, Predicate prune, ArrayList<GNode> list) {
      if (select == null || select.valid(this)) list.add(this);
      if (prune == null || ! prune.valid(this)) {
         for (GNode gchild : gnodes) {
            gchild.selectGNodes(select, prune, list);
         }
      }
      return list;
   }

   /**
    * returns the VJoint for this GNode
    */
   public VJoint getVJoint() {
      return joint;
   }

   private static final int LISTSIZE = 4;

   /**
    * Adds some GNode as a child node.
    * Also updates the parent-child relationship for
    * the VJoints within thisGNode and the child GNode.
    */
   public void addChildNode(GNode sn) {
      if (gnodes == null) gnodes = new ArrayList<GNode>(LISTSIZE);
      if (sn.parent != null) {
         sn.parent.removeChildNode(sn);
      }
      gnodes.add(sn);
      sn.parent = this;
      joint.addChild(sn.getVJoint());
   }

   /**
    * Removes the specified GNode from
    * the List of child gnodes.
    */
   public void removeChildNode(GNode sn) {
      if (gnodes == null) return;
      gnodes.remove(sn);
   }

   /**
    * Returns a List with GNode children of this GNode.
    */
   public List<GNode> getChildNodes() {
      if (gnodes == null) return EMPTYGNODELIST;
      return gnodes;
   }

   /**
    * Returns the parent GNode of this GNode, which could be null.
    */
   public GNode getParent() {
      return parent;
   }

   /**
    * Adds a GShape
    */
   public void addGShape(GShape gshape) {
      if (gshapes == null) gshapes = new ArrayList<GShape>(LISTSIZE);
      gshapes.add(gshape);
   }

   /**
    * Adds  all elements of a List of  GShapes
    */
   public void addGShapes(List<GShape> gshapeList) {
      if (gshapes == null) gshapes = new ArrayList<GShape>(LISTSIZE);
      gshapes.addAll(gshapeList);
   }

   /**
    * Returns a List with the GShape children of this GNode.
    */
   public List<GShape> getGShapes() {
      if (gshapes == null) return EMPTYGSHAPELIST;
      return gshapes;
   }

   /**
    * Determines whether a GNode based scene graph, with this GNode as root,
    * includes some GShapes at all.
    */
   public boolean hasGShapes() {
      if (getGShapes().size() > 0) return true;
      for (GNode childNode : getChildNodes()) {
          if (childNode.hasGShapes()) return true;
      }
      return false;
   }

   /**
    * Searches for a GNode with specified sid. The search is recursive,
    * among the child nodes of this GNode, and include this GNode as well.
    */
   public GNode getPartBySid(String sid) {
      if  (this.sid != null && this.sid.equals(sid)) return this;
      for (GNode childNode : getChildNodes()) {
          GNode gn = childNode.getPartBySid(sid);
          if (gn != null) return gn;
      }
      return null;
   }

   /**
    * Searches for a GNode with specified id. The search is recursive,
    * among the child nodes of this GNode, and include this GNode as well.
    */
   public GNode getPartById(String id) {
      if  (this.id != null && this.id.equals(id)) return this;
      for (GNode childNode : getChildNodes()) {
          GNode gn = childNode.getPartById(id);
          if (gn != null) return gn;
      }
      return null;
   }

   /**
    * Searches for a GNode with specified id and/or sid. The search is recursive,
    * among the child nodes of this GNode, and include this GNode as well.
    */
   public GNode getPart(String id_or_sid) {
      if  (this.sid != null && this.sid.equals(id_or_sid) ) return this;
      if  (this.id != null && this.id.equals(id_or_sid)   ) return this;
      for (GNode childNode : getChildNodes()) {
          GNode gn = childNode.getPart(id_or_sid);
          if (gn != null) return gn;
      }
      return null;
   }

   /**
    * Searches for a GNode with a name matching the specified regular pattern.
    * For example getPartByNamePattern(".*L.*Clavicle$") would find GNodes with names like "CWom0023-L_Clavicle"
    * See the Javadoc for java.util.regex.Pattern for the syntax of allowed regular expressions.
    */
   public GNode getPartByNamePattern(String namePattern) {
      return getPartByNamePattern(Pattern.compile(namePattern));
   }

   /**
    * Searches for a GNode with a name matching the specified (java.util.regex) regular pattern.
    */
   public GNode getPartByNamePattern(Pattern namePat) {
      if (name != null && namePat.matcher(name).matches()) {
          return this;
      }
      for (GNode childNode : getChildNodes()) {
          GNode gn = childNode.getPartByNamePattern(namePat);
          if (gn != null) return gn;
      }
      return null;
   }

   /**
    * recursively renames the sids and names of GNodes
    */
   public void renameJoints(Map<String, String> renaming) {
      String newName = null;
      if (sid != null)                      newName = renaming.get(sid) ; // first try: use sid, if available
//      if (newName == null && name != null)  newName = renaming.get(name); // second try, use name, if available
//      if (newName == null && id != null)    newName = renaming.get(id);   // last try, use id, if available
//      if (newName == null  && name != null) newName = name;               // no renaming found, fall back on name, if defined
//      if (newName == null  && sid != null)  newName = sid;                // no renaming, no name, so use sid
//      if (newName == null  && id != null)   newName = id;                 // no renaming, no name, no sid so use id
//      // By now, newName should not be null, unless all of id, sid, and name were null
      if (newName != null) {
          //System.out.println("GNode Rename: " + id + ", " + name + ", " + sid + " -> " + newName);
          setSid(newName);
          // setName(newName);
      }
      for (GNode childNode : getChildNodes()) {
         childNode.renameJoints(renaming );
      }
   }

//     /**
//    * recursively renames the sids and names of GNodes
//    */
//   public void renameJoints(Map<String, String> renaming) {
//      String newName = null;
//      if (sid != null)                      newName = renaming.get(sid) ; // first try: use sid, if available
//      if (newName == null && name != null)  newName = renaming.get(name); // second try, use name, if available
//      if (newName == null && id != null)    newName = renaming.get(id);   // last try, use id, if available
//      if (newName == null  && name != null) newName = name;               // no renaming found, fall back on name, if defined
//      if (newName == null  && sid != null)  newName = sid;                // no renaming, no name, so use sid
//      if (newName == null  && id != null)   newName = id;                 // no renaming, no name, no sid so use id
//      // By now, newName should not be null, unless all of id, sid, and name were null
//      if (newName != null) {
//          //System.out.println("GNode Rename: " + id + ", " + name + ", " + sid + " -> " + newName);
//          setSid(newName); setName(newName);
//      }
//      for (GNode childNode : getChildNodes()) {
//         childNode.renameJoints(renaming );
//      }
//   }

   /**
    * Sets the translation of the associated VJoint
    */
   public void setTranslation(float[] translation) {
      joint.setTranslation(translation);
   }

   /**
    * Returns the translation of the associated VJoint
    */
   public void getTranslation(float[] result) {
      joint.getTranslation(result);
   }

   /**
    * Returns the translation of the associated VJoint
    */
   public float[] getTranslation() {
      float[] result = Vec3f.getVec3f();
      joint.getTranslation(result);
      return result;
   }

   /**
    * Sets the rotation quaternion of the associated VJoint
    */
   public void setRotation(float[] rotation) {
      joint.setRotation(rotation);
   }

   /**
    * Return the rotation quaternion of the associated VJoint
    */
   public void getRotation(float[] rotation) {
      joint.getRotation(rotation);
   }

   /**
    * Returns the rotation quaternion of the associated VJoint
    */
   public float[] getRotation() {
      float[] result = Quat4f.getQuat4f();
      joint.getRotation(result);
      return result;
   }

   /**
    * Sets the scale vector of the associated VJoint
    */
   public void setScale(float[] scaleVec) {
      joint.setScale(scaleVec);
   }

   /**
    * SeGetsts the scale vector of the associated VJoint
    */
   public void getScale(float[] scaleVec) {
      joint.getScale(scaleVec);
   }

   /**
    * Returns the Vec3f scale vector of the associated VJoint
    */
   public float[] getScale() {
      float[] result = Vec3f.getVec3f();
      joint.getScale(result);
      return result;
   }

   /**
    * Sets the skewing matrix of the associated VJoint
    */
   public void setSkewMatrix(float[] skewMatrix) {
      joint.setSkewMatrix(skewMatrix) ;
   }

   /**
    * Sets the local transform matrix of the associated VJoint
    */
   public void setLocalTransform(float[] m) {
      joint.setLocalTransform(m);
   }

   /**
    * Gets the local transform matrix of the associated VJoint
    */
   public float[] getLocalMatrix() {
      return joint.getLocalMatrix();
   }

   /**
    * Gets the global transform matrix of the associated VJoint
    */
   public float[] getGlobalMatrix() {
      return joint.getGlobalMatrix();
   }

   public void clearLocalLinearTransform() {
      joint.clearLocalLinearTransform();
   }

   public void clearRotations() {
      joint.clearRotation();
      for (GNode child : getChildNodes()) child.clearRotations();
   }

   public void clearJointRotations() {
      if (type == "JOINT" || type =="Joint") {
         joint.clearRotation();
      }
      for (GNode child : getChildNodes()) child.clearJointRotations();
   }

   /**
    * Transforms, recursively, the associated VJoint matrices.
    */
   public void affineTransformVJoint(float[] mat4x4) {
      joint.affineTransform(mat4x4);
      for (GNode child : getChildNodes()) child.affineTransformVJoint(mat4x4);
   }

   /**
    * Transforms, recursively, the attached GShapes
    */
   public void affineTransformGShapes(float[] mat4x4) {
      //joint.affineTransform(mat4x4);
      for (GShape gshape : getGShapes()) gshape.affineTransform(mat4x4);
      for (GNode child : getChildNodes()) child.affineTransformGShapes(mat4x4);
   }

   /**
    * Transforms, recursively, the VJoint matrix and the attached GShapes
    */
   public void affineTransform(float[] mat4x4) {
      joint.affineTransform(mat4x4);
      for (GShape gshape : getGShapes()) gshape.affineTransform(mat4x4);
      for (GNode child : getChildNodes()) child.affineTransform(mat4x4);
   }

//   /**
//    * Removes the scaling transformations from this scenegraph by applying scaling to geometry.
//    */
//   public void removeScaling() {
//      removeScaling(new float[] {1.0f, 1.0f, 1.0f});
//   }
//
//
//
//   /**
//    * Removes the scaling, rotation, and translation transformations from this scenegraph by applying the transformations to geometry.
//    */
//   public void removeAffineTransforms() {
//      removeAffineTransforms(Mat4f.ID);
//   }
//
//   /**
//    * Removes the transforms for this GNode and its descendants
//    * The specified mat4x4 (a 4X4 matrix) is applied to the current transform
//    * T o L, so it becomes ma4X4 o T o L. This transform is then applied to
//    * the geometry attached to this GNode. The transform of this GNode is then set to identity (i.e. no translation, rotation, or scaling)
//     The combined transform is then applied (recursively) to all
//    * child GNodes.
//    */
//   public void removeAffineTransforms(float[] mat4x4) {
//      float[] localMatrix = joint.getLocalMatrix();
//      float[] combinedTransform = Mat4f.getMat4f();
//      Mat4f.mul(combinedTransform, mat4x4, localMatrix);
//      joint.clearLocalAffineTransform();
//      for (GShape gs : getGShapes()) gs.getGMesh().affineTransform(combinedTransform);
//      for (GNode child : getChildNodes()) child.removeAffineTransforms(combinedTransform);
//   }
//
//
   /**
    * Removes the scaling and rotation transformations from this scenegraph by applying the linear part of the transformations to geometry.
    * Translation is modified accordingly, but not eliminated.
    */
   public void removeLinearTransforms() {
      removeLinearTransforms(Mat3f.getIdentity());
   }

   /**
    * Removes the linear component of the transform of this GNode and its descendant.
    * That, the upper left 3X3 part, specifying the linear transform part, will be set to
    * identity, but a translation part will remain.
    */
   public void removeLinearTransforms(float[] mat3x3) {
      float[] localLinear = Mat3f.from4x4(joint.getLocalMatrix());
      float[] combinedTransform = Mat3f.getMat3f();
      Mat3f.mul(combinedTransform, mat3x3, localLinear);
      for (GShape gs : getGShapes()) gs.getGMesh().linearTransform(combinedTransform);
      joint.getTranslation(vec);
      Mat3f.transform(mat3x3, vec);
      joint.setTranslation(vec);
      joint.clearLocalLinearTransform();
      for (GNode child : getChildNodes()) child.removeLinearTransforms(combinedTransform);
   }

   /**
    * Returns the XML encoding of this GNode
    */
   @Override
   public String toString() {
      return toXMLString();
   }

   /**
    * appends the id, sid, name XML attributes to buf.
    */
   @Override
   public StringBuilder appendAttributes(StringBuilder buf) {
      super.appendAttributes(buf);
      appendAttribute(buf, "id", id);
      appendAttribute(buf, "sid", sid);
      appendAttribute(buf, "name", name);
      appendAttribute(buf, "type", type);
    //  if (type != null && (type == "Joint" || type == "JOINT")) {
         appendAttribute(buf, "translation", getTranslation(), ' ');
         appendAttribute( buf, "rotation", getRotation() , ' ');
         appendAttribute( buf, "scale", getScale() , ' ');
   //   }
      return buf;
   }

   /**
    * decodes the id and sid XML attributes.
    */
   @Override
   public void decodeAttributes(HashMap<String, String> attrMap, XMLTokenizer tokenizer) {
      setId(getOptionalAttribute("id", attrMap));
      setSid(getOptionalAttribute("sid", attrMap));
      setName(getOptionalAttribute("name", attrMap));
      setType(getOptionalAttribute("type", attrMap));
      String tr = getOptionalAttribute("translation", attrMap);
      if (tr != null) setTranslation(decodeFloatArray(tr));
      String rot = getOptionalAttribute("rotation", attrMap);
      if (rot != null) setRotation(decodeFloatArray(rot));
      String sc = getOptionalAttribute("scale", attrMap);
      if (sc != null)  setScale(decodeFloatArray(sc));
      super.decodeAttributes(attrMap, tokenizer);
   }

   /**
    * append XML contents section to buf
    */
   @Override
   public StringBuilder appendContent(StringBuilder buf, XMLFormatting fmt) {
      appendXMLStructureList(buf, fmt, gnodes);
      appendXMLStructureList(buf, fmt, gshapes);
      return buf;
   }

   /**
    * decodes XML content section
    */
   @Override
   public void decodeContent(XMLTokenizer tokenizer) throws IOException {
      while (tokenizer.atSTag()) {
         String tag = tokenizer.getTagName();
         if (tag.equals(GNode.xmlTag())) {
            addChildNode(new GNode(tokenizer));
         } else if (tag.equals(GShape.xmlTag())) {
            addGShape(new GShape(tokenizer));
         } else {
            logger.error(tokenizer.getErrorMessage("GNode: skip : " + tokenizer.getTagName()));
            tokenizer.skipTag();
         }
      }
   }

   /*
    * The XML tag for XML encoding
    */
   private static final String XMLTAG = "gnode";

   /**
    * The XML tag for XML encoding
    */
   public static String xmlTag() { return XMLTAG; }

   /**
    * returns the XML tag for XML encoding
    */
   @Override
   public String getXMLTag() {
      return XMLTAG;
   }

   /**
    * Writes a binary encoding to dataOut
    */
   public void writeBinary(DataOutput dataOut) throws IOException {
      BinUtil.writeOptionalString(dataOut, id);
      BinUtil.writeOptionalString(dataOut, sid);
      BinUtil.writeOptionalString(dataOut, name);
      BinUtil.writeOptionalString(dataOut, type);
      BinUtil.writeFloatArray(dataOut, getTranslation());
      BinUtil.writeFloatArray(dataOut, getRotation());
      BinUtil.writeFloatArray(dataOut, getScale());
      BinUtil.writeBinaryList(dataOut, gshapes);
      BinUtil.writeBinaryList(dataOut, gnodes);
   }

   /**
    * Reads a binary encoding from dataIn
    */
   public void readBinary(DataInput dataIn) throws IOException {
      setId(BinUtil.readOptionalString(dataIn));
      setSid(BinUtil.readOptionalString(dataIn));
      setName(BinUtil.readOptionalString(dataIn));
      setType(BinUtil.readOptionalString(dataIn));
      setTranslation(BinUtil.readFloatArray(dataIn));
      setRotation(BinUtil.readFloatArray(dataIn));
      setScale(BinUtil.readFloatArray(dataIn));
      gshapes = BinUtil.readBinaryList(dataIn, GShape.class);
      ArrayList<GNode> childNodes = BinUtil.readBinaryList(dataIn, GNode.class);
      if (childNodes == null) {
         gnodes = null;
      } else {
         for (GNode child : childNodes) addChildNode(child);
      }
   }

}