NextTypes System

NextTypes is a standards based system of storage, processing and transmission of information that integrates the characteristics of other systems such as databases, programming languages, communication protocols, file systems, document managers, operating systems, frameworks, file formats and hardware in a single system tightly integrated using a common data type system.

Third Party Software

The reference implementation uses Java, PostgreSQL and Tomcat. It is distributed in an easily installable WAR file and includes third party libraries to implement some components. In turn, these libraries depend on other libraries for their operation. It is convenient to know its use and license to develop applications on NextTypes.

Software License
Apache Commons CLI Apache 2.0
Apache Commons IO Apache 2.0
Apache Commons Lang Apache 2.0
Apache HttpComponents Apache 2.0
Apache Jackrabbit Apache 2.0
Apache Tika Apache 2.0
Apache Tomcat JDBC Connection Pool Apache 2.0
AspectJ Eclipse Public License 2.0
BouncyCastle MIT
Codemirror MIT
iCal4j BSD 3-Clause License
Imgscalr Apache 2.0
Jackson Apache 2.0
Jakarta Mail EPL 2.0 y GPLv2 con Excepción Classpath
Open Iconic MIT (Icons) y Open Font License (Fonts)
PostgreSQL JDBC Driver BSD-2-Clause License
TinyMCE MIT
Zxing Apache 2.0

Data Types

Each software uses different types of data, so it is necessary to define standard primitive and composite data types for use by all parts of the system. Data types are called "type" and are the core of the system and what gives the project its name.

Bit, byte and type diagram
After the bit and byte the "type" is the data type to define data structures

Primitive Types

The main systems to integrate are PostgreSQL, Java and HTML5. It is necessary to make a comparison of the primitive data types of these systems to find what they have in common and the data types that are more or less standard in all computer systems although they receive different names in one system or another. In addition NextTypes adds other Java classes and data types for your use.

Type PostgreSQL Java HTML5 Input HTML5 Output NextTypes
Composite data type TABLE Type form type
16 bits integer smallint Short number int16
32 bits integer integer Integer number int32
64 bits integer bigint Long number int64
32 bits float real Float number float32
64 bits float double precision Double number float64
Variable length exact integer or decimal numeric BigDecimal number numeric
Boolean boolean Boolean checkbox boolean
Text string character varying String text string
Big text text String textarea text
HTML text text HTMLFragment textarea html
JSON document jsonb JSON textarea json
XML document xml XML textarea xml
URL character varying URL url a url
Email address character varying InternetAddress email mailto: email
Telephone number character varying String tel tel: tel
Date date LocalDate date time date
Time time LocalTime time time time
Date and time timestamp LocalDateTime datetime-local time datetime
Time zone character varying(50) ZoneId select timezone
Color character(7) Color color color color
Binary object bytea byte[] file binary
File composite type File file file
Image composite type Image file img image
Audio composite type Audio file audio audio
Video composite type Video file video video
Document composite type Document file document
Password character(60) String password password

Characteristics of Primitive Types

Once the primitive data types have been identified, it is necessary to define valid characteristics and limits between the different systems to be integrated. All data types can also have the value null for integration with SQL.

Type Name Description
16 bits integer int16 Intege number between -32768 y +32767.
32 bits integer int32 Integer number between -2147483648 y +2147483647.
64 bits integer int64 Integer number between -9223372036854775808 y 9223372036854775807.
32 bits float float32 32 bits floating point number according to standard IEEE 754.
64 bits float float64 64 bits floating point number according to standard IEEE 754.
Variable length exact integer or decimal numeric Variable length exact integer or decimal up to 131072 digits before the decimal point and up to 16383 digits after the decimal point.
Boolean boolean "true" or "false" values.
Text string string Text string encoded in UTF-8.
Big text text Big text encoded in UTF-8.
HTML text html Text in HTML5 format with the same characteristics as "text" and with XML syntax. Allowed tags and attributes are indicated with the configuration parameter "html_allowed_tags", in the following format:
tag1:attribute1,attribute2;tag2;tag3:attribute1
JSON document json Document in JSON format with the same characteristics as "text".
XML document xml Document in XML format with the same characteristics as "text". Allowed tags and attributes are indicated by the configuration parameter "xml_allowed_tags", in the same format as "html_allowed_tags".
URL url URL (Uniform Resource Locator) with the same characteristics as "string".
Email address email Email address with the same characteristics as "string".
Telephone number tel Telephone number with the same characteristics as "string".
Date date Date with year, mounth and day between 4713 BC and 5874897 AD with ISO 8601 format.
Time time Hour, minutes, seconds and microseconds without time zone and with ISO 8601 format.
Date and time datetime Date and time with the same characteristics as "date" y "time".
Time zone timezone Time zone defined in the IANA time zone database.
Color color Color in RGB hexadecimal format. Example:
#30c74d
Binary object binary Bytes array.
File file Binary type composed of two parameters: "content" with the file's byte array and "content_type" with the file type
Image image Image file that also includes a thumbnail of the image in the "thumbnail" parameter.
Audio audio Audio file with the same parameters as "file".
Video image Video file with the same parameters as "file".
Document document Office document file (ODT, DOC, PDF, etc) that includes the "text" parameter with the plain text extracted from the document.
Password password Password encrypted with the bcrypt algorithm in OpenBSD format. Example:
$2y$12$TFhXz5DvNAl0/jUg7hd56eLT52bZXiuBsDrapQ1Tm8LDaB7qaO3o6

Composite Types

Composite types are made up of a series of primitive types and links to other composite types. These links form a network database but using the properties of the relational databases. This system allows easy integration with programming languages and at the same time use all the capabilities of SQL. In the web interface you can see the example type "example", composed with all the primitive types and the composite type "article".

Composite data types have the following properties:

Name Descripction
name Type name.
cdate Creation date in UTC (Coordinated Universal Time) with ISO 8601 format.
adate Last alteration date in UTC (Coordinated Universal Time) with ISO 8601 format.
fields Fields that make up the type can be a primitive type or a link to a composite type. The fields have a name and a series of properties that define them.
indexes Indexes made up of one or more fields. Each of the indexes has a name and a series of properties that define it.
actions Extra actions programmed in a programming language.

The characters allowed in type, fields, indexes and actions names are limited to numbers, lowercase ASCII letters and the character "_", with a maximum length of 30 characters, to ensure compatibility between different systems and limit the risk of code injection.

The properties of the fields are as follows:

Name Description
type Primitive or composite type name.
length Maximum length of text string.
precision Precision in float32, float64 and numeric fields.
scale Scale in float32, float64 and numeric fields.
not_null Possibility that the field can have the null value.
range Minimum (min) and maximum (max) value allowed.

The properties of the indexes are as follows

Nanem Description
fields Names of the fields that make up the index.
mode Index mode. It can be search only (index), force a unique combination of fields (unique), or be used for full text searches (fulltext).

The definition of a composite type can be represented in JSON format or in another format for display, modification, storage or transfer to another system. Below is an example of the definition of the "article_language" type in JSON:

{
  "name" : "article_language",
  "cdate" : "2015-04-01T14:30:16Z",
  "adate" : "2018-09-26T14:59:35.53Z",
  "fields" : {
    "title" : {
      "type" : "string",
      "length" : 254,
      "not_null" : true
    },
    "language" : {
      "type" : "language",
      "length" : 100,
      "not_null" : true
    },
    "text" : {
      "type" : "html",
      "not_null" : true
    },
    "article" : {
      "type" : "article",
      "length" : 100,
      "not_null" : true
    }
  },
  "indexes" : {
    "al_ft_search_index" : {
      "mode" : "fulltext",
      "fields" : [ "title", "text" ]
    }
  },
  "actions" : { }
}

Objects

Similar to object oriented programming languages, an instance of a type is called an "object". Objects have the following properties:

Name Description
type The type of which they are an instance.
id Unique identifier within the type of which it is an instance. There may be another object of a different type with the same id. The allowed characters are limited to numbers, lowercase ASCII letters and the "-" and "." characters to ensure compatibility between different systems and limit the danger of code injection. If an id is not entered when creating the object an UUID is automatically assigned. The maximum size is 100 characters.
name Descriptive name of the object. It is not stored in the system but is dynamically created with the result of an SQL query or the execution of a function that can concatenate several fields of the object or of several objects and add any other text.

The query is indicated with the "id_name" configuration parameter and receives the language as a parameter, so the descriptive name may be different depending on the language. If the way to create the "name" is not indicated the value of the "id" is used.

The following example shows how is used as "name" for the type "article" the "title" column from "article_language" type depending on the language.:
article.id_name=select a.id, al.title as name from article a left join article_language al on (a.id=al.article and al.language=?)
cdate Creation date in UTC (Coordinated Universal Time) with ISO 8601 format.
udate Last update date in UTC (Coordinated Universal Time) with ISO 8601 format.
backup Indicator if the object was backed up after the last modification.
fields Fields of which it is composed. In the case of a field of primitive type it contains the value. In the case of a composite type it contains the "id" of the object it points to.

When an object is stored in a system the storage format is the one used by that system. When that object is to be transmitted from one system to another it must be encoded in JSON or another format. In objects and fields of composite types the "name" can be included to expand the information but only the "id" is necessary. Following is an example of an "article_language" object in JSON:

{
  "type" : "article_language",
  "id" : "6539cb3a-cf6d-11e4-a8be-001f3c35b55c",
  "name" : "6539cb3a-cf6d-11e4-a8be-001f3c35b55c",
  "cdate" : "2015-04-01T14:30:16Z",
  "udate" : "2021-01-13T20:30:31.886528Z",
  "backup" : false,
  "fields" : {
    "title" : "NextTypes System",
    "language" : {
      "id" : "en",
      "name" : "English"
    },
    "text" : "NextTypes is a standards based system of storage, processing and transmission of information ...",
    "article" : {
      "id" : "system",
      "name" : "NextTypes System"
    }
  }
}

Universal Object Identifier

Each object is universally identified by its id, type and the server it is on.

host.example.com/type/id

This identifier can be used in QR codes or otherwise to access an object from any device or to tag objects real.

Export of Types and Objects

Types and objects are exported in two different types of containers. The "name" parameter of the objects is not included.

Object Container

The object container stores a group of objects of the same type. Its properties are as follows:

Name Description
format Indicates the type of container. Its value is "nexttypes_objects".
version Format version. Between versions there are changes in the format and knowing the version allows the import of different formats taking into account their peculiarities.
type Type of the objects.
count Number of objects in the container.
items Array of objects encoded as indicated in section "Objects".

Here is an example omitting the objects:

{
  "format" : "nexttypes_objects",
  "version" : "1.0",
  "type" : "article_language",
  "count" : 6,
  "items" : [ ]
}

Types Container

The type container stores definitions of types and can also include containers for objects of those types. Its properties are as follows:

Nanem Description
format Indicates the type of container. Its value is "nexttypes_types".
version Format version.
date Container creation date in UTC.
types Associative array with the name of the type and its encoding as indicated in the section "Composite Types".
objects Associative array with the type name of the objects and the object container.

Below is shown an example omitting the types definition and the objects containers:

{
  "format" : "nexttypes_types",
  "version" : "1.0",
  "date" : "2020-11-14T22:53:00.688057Z",
  "types" : {
    "article" : {},
    "article_author" : {}
  },
  "objects" : {
    "article" : {},
    "article_author" : {}
  }
}

Systems Integration

Integration consists of adapting the NextTypes data types to the system to be integrated. Currently the main integrated systems are PostgreSQL, Java and HTML5.

PostgreSQL

This relational database manager with its large number of primitive types, the possibility of creating new types and its capabilities of Transactional DDL and deferrable constraints allows to create a data system with a high level of abstraction.

As indicated in the section "Primitive Types" several NextTypes data types correspond to PostgreSQL primitive types, some are specialized variants of these and some are new primitive types.

Each of the composite data types in NextTypes corresponds to a PostgresSQL table. Below you can compare the definition of the "article_language" type in JSON and the definition of the table with the same name in PostgreSQL using the "psql" program.

{
  "name" : "article_language",
  "cdate" : "2015-04-01T14:30:16Z",
  "adate" : "2018-09-26T14:59:35.53Z",
  "fields" : {
    "title" : {
      "type" : "string",
      "length" : 254,
      "not_null" : true
    },
    "language" : {
      "type" : "language",
      "length" : 100,
      "not_null" : true
    },
    "text" : {
      "type" : "html",
      "not_null" : true
    },
    "article" : {
      "type" : "article",
      "length" : 100,
      "not_null" : true
    }
  },
  "indexes" : {
    "al_ft_search_index" : {
      "mode" : "fulltext",
      "fields" : [ "title", "text" ]
    }
  },
  "actions" : { }
}
nexttypes=# \d+ article_language
                                               Tabla «public.article_language»
 Columna  |            Tipo             | Ordenamiento | Nulable  | Por omisión | Almacenamiento | Estadísticas | Descripción 
----------+-----------------------------+--------------+----------+-------------+----------------+--------------+-------------
 id       | character varying(100)      |              | not null |             | extended       |              | 
 cdate    | timestamp without time zone |              | not null |             | plain          |              | 
 udate    | timestamp without time zone |              | not null |             | plain          |              | 
 backup   | boolean                     |              | not null |             | plain          |              | 
 title    | character varying(254)      |              | not null |             | extended       |              | string
 language | character varying(100)      |              | not null |             | extended       |              | language
 text     | text                        |              | not null |             | extended       |              | html
 article  | character varying(100)      |              | not null |             | extended       |              | article
Índices:
    "article_language_pkey" PRIMARY KEY, btree (id)
    "al_ft_search_index" gin (to_tsvector('simple'::regconfig, (title::text || ' '::text) || text))
Restricciones de llave foránea:
    "article_language_article" FOREIGN KEY (article) REFERENCES article(id) ON UPDATE CASCADE DEFERRABLE
    "article_language_language" FOREIGN KEY (language) REFERENCES language(id) ON UPDATE CASCADE DEFERRABLE

The "id" identifier is a variable length text column of a maximum of 100 characters and is the primary key of the table. The columns description is used to indicate their NextTypes data type. The index with "fulltext" mode "al_ft_search_index" is an index that uses the PostgreSQL full text search system and the "language" and "article" composite types fields point to the "id" column of the "language" and "article" tables using deferrable foreign keys.

You can also inspect the data type with the pgAdmin graphical program or another graphical database management application.

article_language type seen from PostgreSQL PGAdmin
article_language type seen from PostgreSQL pgAdmin.

Since the types do not usually change and their information is continuously required as it is the basis of the system, the description of the fields, indexes and content type of the fields are stored in memory so as not to have to continuously read this information from the database data and speed up system operation.

Java

In programming languages the types, fields, indexes, range of allowed values and objects are represented by the Type, TypeField, TypeIndex, FieldRange and NXObject classes. The Tuple class provides a common interface for accessing different resources such as an object, a row of an SQL query or the parameters of an HTTP request. Some classes are also added for HTML, JSON, XML, URL, Color, File, Image, Audio, Video and Document primitive types.

Unlike ORM or DSL systems, NextTypes does not define a correspondence between database tables and programming language classes but uses these generic classes to bring the relational model to the programming language.

HTML5

NextTypes makes use of the HTML5 forms with specific input elements for different data types such as "text", "tel", "url", "email", "password", "date", "time", "datetime-local", "number", "color", "checkbox" and "file". It also expands the controls of these elements with new graphic components and the use of text editors such as Codemirror and TinyMCE. It also makes use of the output elements like "a", "time", "img", "audio" and "video".

In the web interface you can see the "example" type with all the data types, their input elements and text editors.

System Types

The system depends for its operation on a minimum group of types that are listed below:

Type Description
languageSystem language. Its "id" is an ISO 639 code.
language_languageLanguage name in a specific language.
userSystem user.
user_certificateUser digital certificate.
groupSystem group.
group_userGroup user.
group_languageGroup name in a specific language.
image_linkImage with link.
image_link_languageImage with link language.

NextTypes System

Based on the standard data types for integration a system is created based on the concept of Model View Controller composed of the following modules:

NextTypes System Diagram
NextTypes System Diagram.

Configuration

The system has four types of configuration parameters:

The configuration parameters are stored in ".properties" files that are read by the Settings class and its subclasses. The system includes files with default settings in "com.nexttypes.settings.defaults".

In the file WEB-INF/web.xml is defined the variable "settings_directory" that points to a directory where you can create a replica of those ".properties" files in which to give different values to the parameters. By default the directory is "/etc/nexttypes/settings" but it can be changed to another. If we have more than one NextTypes system on the same server, it will be necessary to create different directories for each system. Included in the source code are two sample configuration directories.

There is also the ability to modify the settings in the WAR file to distribute it with the desired settings.

Types Parameters

Each of the types can have different configuration parameters that are saved in the "types.properties" file and read with the class TypeSettings. The parameters are defined on a line in the following format:

type.property.subproperty.subproperty...=value

The "*" character can be used to assign the parameter to different types with the same root and their parts separated by the "_" character. For example, the "user*" parameters apply to "user" and "user_certificate" but would not apply to "users". Parameters assigned to "user_certificate" take precedence over "users*".

There are four types of configuration parameters:

Groups Parameteres

The groups configuration files allow you to assign different values to the configuration parameters of the types for certain groups.

Language Parameters

These parameters are stored in a different file for each system language, they are read with the LanguageSettings class and are used for settings that differ between languages as text strings or date formats.

Permissions

Users are represented by the "user" type, groups by the "group" type and the membership of a user to a group by "group_user" type. The "guest" user represents unauthenticated users. By default the "administrators" group has permissions to perform all actions.

{
  "name" : "user",
  "cdate" : "2015-06-24T17:40:03Z",
  "adate" : "2015-06-24T17:40:03Z",
  "fields" : {
    "first_name" : {
      "type" : "string",
      "length" : 250,
      "not_null" : true
    },
    "second_name" : {
      "type" : "string",
      "length" : 250,
      "not_null" : true
    },
    "time_zone" : {
      "type" : "timezone",
      "length" : 50,
      "not_null" : true
    },
    "email" : {
      "type" : "email",
      "length" : 250,
      "not_null" : true
    },
    "password" : {
      "type" : "password",
      "length" : 60,
      "not_null" : false
    }
  },
  "indexes" : {
    "user_email_index" : {
      "mode" : "unique",
      "fields" : [ "email" ]
    }
  },
  "actions" : { }
}
  
{
  "name" : "group",
  "cdate" : "2015-06-24T17:40:03Z",
  "adate" : "2015-06-24T17:40:03Z",
  "fields" : { },
  "indexes" : { },
  "actions" : { }
}

{
  "name" : "group_user",
  "cdate" : "2015-06-24T17:40:03Z",
  "adate" : "2015-06-24T17:40:03Z",
  "fields" : {
    "group" : {
      "type" : "group",
      "length" : 100,
      "not_null" : true
    },
    "user" : {
      "type" : "user",
      "length" : 100,
      "not_null" : true
    }
  },
  "indexes" : {
    "group_user_index" : {
      "mode" : "unique",
      "fields" : [ "group", "user" ]
    }
  },
  "actions" : { }
}

Using the "allowed_users" and "allowed_groups" configuration parameters in the "permissions.properties" file are indicated the users and groups that have permission to execute actions of the nodes, views and controllers for a certain type.

In order to assign permissions to objects, limit which objects can be referenced or create custom groups you can subclass the Permissions class and configure it with the "permissions" parameter.

user*.permissions=com.nexttypes.settings.UserPermissions

In the system source code you can see the classes UserPermissions or ProjectPermissions as examples. UserPermissions only allows to perform actions on a user and create "user_certificate" objects that refer to that user to administrators and to the user himself. ProjectPermissions limits the actions on "project" and project* objects to the owner of the project and to project members. To make these permission limitations they reimplement the "isAllowed(type,objects,action)" and isAllowedToMakeReference" methods.

Modules Parameters

Each module in the system can have configuration parameters that are saved in a file with the module name and the extension ".properties". The Settings class is used to process these files.

Security

Through the Checks class and the NodeSecurity and ViewSecurity aspects the user permissions are checked to execute the methods of the nodes and views. It is also checked that the names of the types, fields, indexes, identifiers, languages and views comply with the system restrictions to ensure proper operation and avoid code injection. Below is the list of restrictions on names:

Antivirus

With the ClamAV class, which uses the antivirus of the same name, virus scanning can be performed on the binary, file, document, image, audio and video fields. To activate virus scanning on objects of a type in all or some of its actions the "antivirus" configuration parameter is used.

*.actions.antivirus=false
example.actions.antivirus=true

In the "clamav.properties" config file the "host" and "port" parameters are configured to connect to the ClamAV server.

Activity Registration.

NextTypes using the Logger and FileHandler classes allows you to store logs of system activity from informational messages to critical errors. In the config file "logger.properties " the following parameters can be configured:

Parameter Description
langMessages language.
directoryDirectory where to save the log files.
prefixLog file prefix. To the prefix is appended the UTC date and the extension ".log". When starting a new day a new file is created.
nexttypes-2020-12-23.log
levelMinimum level of importance of the messages to be logged: info (informational messages), warning (normal errors) and severe (serious errors).

If the activity log system fails and the log file cannot be written, as a last resort an error is displayed by the standard output.

Log File Format

Each of the records in the file is made up of two parts. The first part is common to all system modules and includes the date and time in UTC with ISO 8601 format, level of importance, class in which it originated, user who executed the action and IP address from which the action was executed. The second part depends on the module, for example in the HTTP module the method and address of the request are indicated. The PostgreSQL module indicates the SQL query made.

2020-12-22T19:02:23.453Z INFO com.nexttypes.protocol.http.HTTPServlet guest 127.0.0.1 GET http://localhost:8080/
2020-12-22T19:17:13.756Z INFO com.nexttypes.nodes.PostgreSQLNode guest 192.168.1.35 select count(*) as objects, max(udate) as udate from "article"

Node

Node is a storage system inspired by SQL and with a slightly higher level of abstraction than JDBC which provides protection against SQL injection, transaction management and facilitates the basic tasks of creating, reading, modifying and deleting types and objects. It is possible to chain several Node subclasses that process the information until reaching the final node. Each system module has in its configuration the "next_node" parameter that indicates the node to which it must connect.

next_node=com.nexttypes.nodes.ControllersNode

Connection Modes

Nodes can be run in three modes with different privileges to limit the possibility that an attacker can perform illegal actions:

Execution of queries and actions with protection against SQL injection

The system has the "query" and "execute" methods to perform queries and write actions easily with the execution of a single method. They use prepared statements to separate the values of the columns (fields) from the SQL statement to avoid SQL injection attacks. They also add the possibility of using the names of the tables (types) and the columns (fields) as parameters of prepared statements, using the "#" character, and check that their names are valid and do not present danger of SQL injection. It also offers the possibility of using arrays as parameters.

Tuple[] tuples = nextNode.query("select title from # where id in (?)", type, objects);

Transactions

The Node class implements the AutoCloseable interface, so it can be used in a try-with-resources block.

When a Node object is created a connection to the database is opened with "autocommit" disabled. When the object is closed with the "close" method, it's automatically executed the "commit" method that performs the "commit" in the database. In this way the block try-with-resources corresponds to a transaction.

If you want to save the information in the database at an intermediate point, before closing the connection, you can execute the "commit" method manually. Subtransactions can also be made using "save points".

The "execute" method, before executing a sentence, creates a "savepoint" and makes "rollback" if a failure occurs or the rows affected are not the expected ones.

Concurrency Control

NextTypes uses the types alteration date and objects update date to implement an optimistic concurrency control system. When reading a type or object, the date of the last modification can also be read. When the type or object is updated, that date can be passed to the system in the "alter" and "update" methods. The system checks that the date matches the date of the type or object on the storage system. If the dates do not coincide it is indicative that the type or object has been modified after the last user reading and if your changes are saved the changes made in the other modification will be lost. When this happens the modification is canceled and the user is informed to review the changes that have been made.

Concurrency control error when trying to update an article that has been updated by another user or in another tab
Concurrency control error when trying to update an article that has been updated by another user or in another tab.

Controller

If the default functionality of Node is not enough for some type you can create a controller that adds the desired functionality by creating a subclass of the class Controller and reimplementing the necessary methods. Controllers are run through the ControllersNode node. NextTypes includes various controllers for its basic operation as UserCertificateController and some examples like EmailController.

The controller receives as initialization parameters the type with which it is executed, the authentication information and the next node (nextNode) on which the action is to be performed.

The following example shows the reimplementation of EmailController "insert" method used by the "user_email" type so that when an object of this type is created, in addition to performing the default action in "nextNode", an email is sent using the Email class.

public class EmailController extends Controller {

	public EmailController(String type, Auth auth, Node nextNode) {
		super(type, auth, nextNode);
	}

	@Override
	public ZonedDateTime insert(NXObject object) {
		
		ZonedDateTime udate = nextNode.insert(object);
		new Email(object, Format.HTML).send();
		return udate;
	}
}

Once the controller is created it is assigned to the type with the following configuration line:

user_email.controller=com.nexttypes.controllers.EmailController

Additional Actions

In addition to reimplementing the methods of the Controller class new actions can be added that are executed through the Node "executeAction" methods. A new method is created and marked with the "Action" annotation. Here is the example of ImageController "resize" action.

@Action(RESIZE)
public ActionResult resize(String[] objects, Integer width, Integer height) {
		
}

The actions and the types of their parameters are defined in a JSON file similar to the fields of a type. For example the ImageController uses the image-actions.json file.

{
	"resize": {
		"width": {
			"type": "int32",
			"precision": 32,
			"scale": 0,
			"not_null": true
		},
		"height": {
			"type": "int32",
			"precision": 32,
			"scale": 0,
			"not_null": true
		}
	}
}

In the controller constructor the path of the file is indicated by assigning it to the variable "actionsInfo".

public ImageController(String type, Auth auth, Node nextNode) {
	super(type, auth, nextNode);
		
	actionsInfo = "/com/nexttypes/controllers/image-actions.json";
}

Data format conversion

The controllers also allow you to take data in any format and convert it to an object. The following is an example of the "update" method of the controller ProjectController that uses an event from an iCalendar file to update a "project_meeting" object. This allows a CalDAV client to communicate with the node.

@Override
public ZonedDateTime update(String id, byte[] data) {
	
	if (PROJECT_MEETING.equals(type)) {
		ICalendar calendar = new ICalendar(data);
		VEvent vevent = calendar.getFirstEvent();

  		String startDateString = vevent.getStartDate().getValue();
		String endDateString = vevent.getEndDate().getValue();

		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Constants.BASIC_DATETIME_FORMAT);

		NXObject object = new NXObject(type, id);
		if (startDateString != null) {
			LocalDateTime startDate = LocalDateTime.parse(startDateString, formatter);
			object.put(KeyWords.DATE, startDate.toLocalDate());
			object.put(KeyWords.START_TIME, startDate.toLocalTime());
		}

		if (endDateString != null) {
			LocalDateTime endDate = LocalDateTime.parse(endDateString, formatter);
				object.put(KeyWords.END_TIME, endDate.toLocalTime());
		}

		object.put(KeyWords.DESCRIPTION, vevent.getDescription().getValue());

		return nextNode.update(object);
	} else {
		return null;
	}
}

Similarities to SQL Triggers

The controllers work similar to the SQL database triggers with some differences:

View

Views are subclasses of the View class that connect to Node subclasses in read only mode to display one or more specific types using a data format such as HTML or JSON. For example, an article_language object can be displayed in JSON format, the software_release objects list in RSS format or the project_meeting objects list as an iCalendar file or as an HTML calendar.

Views can also display the forms required to edit the types and objects. Some views instead of directly accessing types and objects take data from SQL queries defined in configuration parameters for each type, converting a SQL query into a view.

The View class implements the AutoCloseable interface so that it can be used in a try-with-resources block. When it is closed, it closes the instance of Node that it has opened. View is an abstract class and only implements the "getVersion" method to display the NextTypes system version and the "notFound" and "unauthorized" methods to show errors. Each subclass of View can implement the following methods:

Method Description
getVersion NextTypes system version.
getTypesInfo System types list with information.
getTypesName System types names list.
getType Type definition.
getReferences References between types list.
createForm Type creation form.
alterForm Type alteration form.
renameForm Type renaming form.
insertForm Object insertion form.
updateForm Object updating form.
updateIdForm Object identifier updating form.
updatePasswordForm Object password field updating form.
executeActionForm Execution form of an action from a type controller.
importTypesForm Import types form.
importObjectsForm Import objects form.
loginForm User session login form.
select Type objects list.
getNames Type objects list with "id" and "name".
preview Type objects list preview.
calendar Type objects list as a calendar.
get Object view.
getField Object field view.
getFieldDefault Type field default value.
getElement Object field element view. For example an HTML fragment identified by an "id".
filterComponent Type objects list filter component.
selectComponent Type objects list component.
notFound Type, object, field or element not found.
unauthorized Unauthorized action.

The views to be used by the different types are configured as follows:

#default views for all types
*.views.html=com.nexttypes.views.HTMLView
*.views.json=com.nexttypes.views.SerialView
*.views.xml=com.nexttypes.views.SerialView
*.views.smile=com.nexttypes.views.SerialView
*.views.webdav=com.nexttypes.views.WebDAVView
*.views.icalendar=com.nexttypes.views.ICalendarView
*.views.rss=com.nexttypes.views.RSSView

#views for type article
article.views.html=com.nexttypes.views.ArticleView
article.views.rss=com.nexttypes.views.ArticleView

#views for type software
software.views.html=com.nexttypes.views.SoftwareView

Content

Once the view is created it is encapsulated in a Content object that is passed to the protocol and contains the following parameters:

Parameter Description
status HTTP status code.
value View content.
contentType Content-Type HTTP header that specifies the content type (for example application/xhtml+xml) and the character set (by default in NextTypes charset=utf-8 is used). The complete header would be as follows:
application/xhtml+xml;charset=utf-8
NextTypes provides the Format enumeration with the types used in the system.

The "file", "image", "audio", "video" and "document" types have a "content_type" parameter with their content type. In other fields the "Content-Type" can be indicated in the configuration as follows:
example.fields.text.content_type=application/x-latex
headers Rest of HTTP headers such as Content-Disposition or Content-Security-Policy. NextTypes provides the HTTPHeader enumeration with the headers used on the system.

With the header Content-Disposition you can inform the browser that the content should be saved to a file by setting the "disposition-type" to "attachment" and indicating the name of the file with the "filename" parameter as indicated in Grammar section. Here is an example:
"attachment; filename=article.json"
The Content-Security-Policy HTTP header indicates the origin restrictions of the content that is allowed to be included in the HTML document to avoid XSS attacks. The content can be Javascript, images or CSS. The origins are embedded in the HTML document, from a file on the same server from which the HTML document is served or from another server. By default NextTypes only allows content to be included from files on the same server. Additionally it allows images with data: URL and CSS rules embedded in the HTML document with the attribute "style". It is configured with the "content_security_policy" configuration parameter as follows
*.content_security_policy=default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'

Standard Views

NextTypes includes HTML, Serial, RSS, iCalendar, WebDAV, CalDAV, Article and Software views as standard.

HTML

The HTMLView uses HTML5 to show the types and objects as well as the basic forms to create and edit them. In this way it is very easy to add a new type of data to the system. Later, if necessary, the default system can be adapted to the needs that arise.

The HTMLView class implements the following View methods:

Method Description
getTypesInfo System types list with information.
getType Type definition.
getReferences References between types list.
createForm Type creation form.
alterForm Type alteration form.
renameForm Type renaming form.
insertForm Object insertion form.
updateForm Object updating form.
updateIdForm Object identifier updating form.
updatePasswordForm Object password field updating form.
executeActionForm Execution form of an action from a type controller.
importTypesForm Import types form.
importObjectsForm Import objects form.
loginForm User session login form.
select Type objects list.
preview Type objects list preview.
calendar Type objects list as a calendar.
get Object view.
getField Object field view.
getFieldDefault Type field default value.
getElement Object field element view. For example an HTML fragment identified by an "id".
filterComponent Type objects list filter component.
selectComponent Type objects list component.
notFound Type, object, field or element not found.
unauthorized Unauthorized action.
Templates

HTMLView uses the HTML class to load an HTML document as a template and modify its DOM in the same way as with Javascript. The templates are stored in the configuration subdirectory "templates". This system allows you to completely separate the HTML design from the programming language code. For the developer the HTML document is another component to use in software development. The template to use for a type is indicated by the "template" parameter.

*.template=default.html

The HTML template should have the following sections:

Tag Description
title Page title. It is assigned the appropriate value based on the view page. In the case of an object view, it is assigned the descriptive name of the object.
header "header" element for the page header that includes the following components:
  • "div" element for the logo.
  • "div" element for the logged in user name and the log out button.
  • "nav" element for the languages list.
  • "form" element for the full text search.
menu "nav" element for the general menu of the website.
main "main" element for the main section where the data is displayed. Includes an "noscript" element to display an alert message if Javascript is disabled. On one side is the "sidebar" "div" that includes a "nav" element with the menu with the standard actions of the type ("type-menu") and another "nav" for additional actions ("actions").
footer "footer" element for the footer where it is included a "div" element for the QR code of the object ("qrcode") and another "div" for the links to the validators of compliance of the page with the standards used. The QR code is generated with the QRCode class and its value is the universal object identifier.

Below is an example template with the required sections:

<html>

<head>
	<title></title>
</head>

<body>

<header>
	<div id="logo"/>
	<div id="user"/>
	<nav id="langs"/>
	<form id="search"/>
</header>

<nav id="menu"/>
	
<main>
	<noscript/>
	<div id="sidebar">
		<nav id="type-menu"/>
		<nav id="actions"/>
	</div>
</main>

<footer>
	<div id="qrcode"/>
	<div id="validators"/>
</footer>

</body>

</html>
Menus

The control panel links are included in the general menu of the "menu" element if it is activated with the "show_control_panel" variable and the user has permissions to see the destination of those links.

*.show_control_panel=true

Also you can add a custom menu with the information from a JSON file indicating the sections and links for each section. This file is processed by the Menu and MenuSection classes. These files are saved in the "menus" directory of the configuration and configured with the "menu" parameter.

*.menu=menu.json

Each of the sections has a "title" and a series of "archors". Each anchor has a "text" and an "href" address. The titles and texts are variables of the language configuration files that have a text string for each language of the system. For example the variable "project" is assigned the value "Proyecto" in Spanish and "Project" in English.

[{
   "title" : "project",
   "anchors" : [ {
      "text" : "home",
      "href" : "/article/home"
   }, {
      "text" : "system",
      "href" : "/article/system"
   }, {
      "text" : "software",
      "href" : "/software/nexttypes"
   }, {
      "text" : "installation",
      "href" : "/article/installation"
   }, {
      "text" : "contact",
      "href" : "/user"
   } ]
}]
Images

In "image_link" and "image_link_language" objects a list of images is saved that can have a link, a description, an alternative text and a title. "Image_link_language" objects can contain a different image and information for each language and take precedence over "image_link" objects.

To include one of these images in the HTML code it is necessary to include a "div" element with the "image" class and indicate using the custom data attributes "data-id" and "data-lang" the "id" and language of the image.

<div class="image" data-id="system" data-lang="en">

The "images" method of the HTMLView class finds all "div" elements of the HTML document with the class "image" and adds them the corresponding image with an "img" element with alternate text (alt) and an optional title (title). In the "src" attribute the "image" field of the "image_link" or "image_link_language" objects is used.

If the "image_link" or "image_link_language" object has a link the image is inserted in an "a" element with that link. If the object "image_link_language" includes a description the image is inserted in an "figure" element and the description in a "figcaption" element.

<div class="image" data-id="system" data-lang="es">
   <figure>
      <a href="/article/system?lang=es&view=html">
         <img alt="Diagrama Sistema NextTypes"
            src="/image_link_language/e3f7b708-caab-11e4-b8b4-001f3c35b55c/image"
            title="Diagrama Sistema NextTypes"/> 
      </a>
      <figcaption>Diagrama Sistema NextTypes.</figcaption>
   </figure>
</div>
Text Editors

The text fields "text", "html", "json" and "xml" use a "textarea" element and they can have a text editor adapted to their format by using CodeMirror and TinyMCE. By default the "text" fields only have the normal browser editor and the rest of the fields use CodeMirror with one of its modes. The "html" and "xml" fields use the "xml" mode and the "json" fields the "javascript" mode configured to edit JSON.

The Codemirror editor mode of a field can be configured with the "editor" parameter. Furthermore NextTypes adds the "visual" mode to use TinyMCE instead of Codemirror and the "json" mode, which is equivalent to {name: "javascript", json: true}.

user_email.actions.fields.message.editor=visual

The HTMLView class using the "textEditors" method adds to the header of the HTML document the Javascript and CSS files required for TinyMCE, CodeMirror and Codemirror "xml" and "javascript" modes. For the rest of the modes it is necessary to add the necessary files in the template or with a subclass of HTMLView.

<head>
   <script src="/static/lib/codemirror/lib/codemirror.js"/>
   <script src="/static/lib/tinymce/js/tinymce/tinymce.min.js"/>
   <link href="/static/lib/codemirror/lib/codemirror.css" rel="stylesheet" type="text/css"/>
   <script src="/static/lib/codemirror/mode/xml/xml.js"/>
   <script src="/static/lib/codemirror/mode/javascript/javascript.js"/>
</head>
QR Code

The "qrcode" method of the HTMLView class uses the QRCode class to insert in the "div" element with "qrcode" id an image with the QR code of the universal identifier of the displayed object. A data: URL is used, in the PNG format encoded in Base64, so as not to have to expose the QR code generation system to external requests. The "alt" and "title" attributes also include the code value. Here is an example:

<div id="qrcode">
   <img alt="demo.nexttypes.com/article/system"
      src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAIAAAABc2X6AAADl0lEQVR4Xu2PQXIEMQgD8/9Pbw5U1rLbwpqt5DKZPlGiAfvr9c/4WoO783z47jwfvjvPh+/O8+G783wYfMWskz+za3rKFZc75n0bAiNmnTx9bE13t1zumPdtCIxgkTrj+A+zu6JOUjsS5/V8eAMPK86p2jHmd1N5l3nVDYGBpYpzqnaM+d1U3mVedUNgYKlCp0+Ys6to15l0GgIDSxU6fcKcXUW7zqTTEBhYqnzmOOa54bNW6DQEBpYqnzmOeW74rBU6DYERLHKHXc2kakLTkTiv58MbxvET6v9FnVB+Q2DEqP8XdUL5DWfjKnqYT2GtSZ//Cn+wUR7Kp7PWpM9/hfNGnudT6PRdmr2jXZdXcuTscSkP0Om7NHtHuy6v5EjqFTyWdKtWXF5wA33NL3FtUo/xsOtWrbi84Ab6ml/iPKkHeGw84QftOkdRx03RcfWRs9evrkTRrnMUddwUHVcfST3CM3yEw025fEx603UXzoaDBzQZT9jhplw+Jr3puguBAVbDO0w0Z8Jcu1o75rkNgQFWwztMNGfCXLtaO+a5DWdD0aU84LqsFeZMNNcuTXW2nA2FZ5Iua4U5E821S1OdLWej4Do9o12tmQz7U1/RrnMWzkbBdfOh0dWaybA/9RXtOmfhbCjh0tfu0XN/4LqVK6uROQtnQwmXvm7wYV3HWhkz3lSHcMp1XdIQe+YRVStjxpvqEE65rksaYg9oTqfvknJ61Lw6+ya19YCeYc2EXVJOj5pXZ9+cbZ6Z++dc0Zym1g6dUvrum8CQRW5pnyua09TaoVNK331zNnL4rKRmUjUdRZ3eXEi9BJ5PaiZV01HU6c2Fs9ev48ned3Bq7N3BKa0bAqNdVF11et/BqbF3B6e0bjgbVxmP8k9xieZ0XM6kIfVy6rw+gg9yieZ0XM6k4ezVugT686Y96utUXzOp+sjZ0wM99OdNe9TXqb5mUvWRs5esc06SV90nCvPeXwiMYJFzkrzqPlGY9/5CYMgiXc18zOweQUdhd8zvUPMS50k9MB9d8zHzrz4891fK6c28O3btki2BgTNK4ijl9GbeHbt2yZbAwBmFjtI7TJi7mgm7WwIDSxU6Su8wYe5qJuxuCYxgEQ9zSnPtrukO7tGkzxcCI1ikTtWc0ly7a7qDezTp84XAiFGfs0miubIau9l5wnL2dGmP+pxNEs2V1djNzhOW1LsNz4fvzvPhu/N8+O48H747z4fvzjdVMRvq+70A4wAAAABJRU5ErkJggg=="
      title="demo.nexttypes.com/article/system"/>
</div>
Calendar

The HTML view includes the ability to view the list of objects of a type such as a calendar. The view takes as parameters the year and the month. The calendar is created from the parameters "id", "summary", "date", "start_time" and "color" of the query indicated in the configuration parameter "calendar.select".

project_meeting.calendar.select=select pm.id, concat(p.name,': ',pm.summary) as summary, pm.date, pm.start_time, p.color from project p join project_meeting pm on p.id=pm.project
Serial

The SerialView implements various View methods and uses the Serial class to display the information in JSON, XML and Smile formats. This view is used to remotely access the data, for example with Javascript.

MethodDescription
getTypesInfoSystem types list with information.JSONXML
getTypesNameSystem types names list.JSONXML
getTypeType definition.JSONXML
getReferencesReferences between types list.JSONXML
selectType objects list.JSONXML
getNamesType objects list with "id" and "name".JSONXML
getObject view.JSONXML
RSS

The RSSView implements the "select" method of View and uses the RSS class to display the type objects list in RSS format.

The elements of the RSS feed are formed from the "id", "title", "description" and "pub_date" parameters of the results of an SQL query indicated in the configuration parameter "views.rss.select". The following is an example of the query used for the "software" type:

software.views.rss.select=select s.id, concat(sl.title,' ',sr.version) as title, left(sl.description,400) as description, sr.cdate as pub_date from software s left join software_language sl on (s.id=sl.software and sl.language=?) left join software_release sr on s.id=sr.software order by sr.cdate desc

When a type has the "views.rss.select" parameter configured, in the HTML view a "link" element is added in the header with the address of the RSS feed of the object or of the list of objects that is being displayed. In the type menu a link with the same address is added.

<link href="/article?lang=es&view=rss" rel="alternate" title="RSS" type="application/rss+xml"/>

If you need to create the view from other parameters you can create a subclass of View and assign it as an RSS view.

article.views.rss=com.nexttypes.views.ArticleView
ICalendar

The ICalendarView implements the "select" method of View using the ICalendar class to display the type objects list in iCalendar format.

The calendar is formed by taking the "id", "summary", "start_date", "end_date" and "description" parameters of the results of the SQL query indicated in the configuration parameter "views.icalendar.select".

project_meeting.views.icalendar.select=select pm.id, pm.udate, concat(p.name,': ',pm.summary) as summary, pm.description, (pm.date+pm.start_time) as start_date, (pm.date+pm.end_time) as end_date from project p join project_meeting pm on p.id=pm.project

When a type has the "views.icalendar.select" parameter configured, in the HTML view a link to the iCalendar view is added in the type menu. If you need to create the view from other parameters you can create a subclass of View and assign it as an iCalendar view.

With this view you can see the objects on a client that can read iCalendar files, such as Thunderbird.

project_meeting objects in Thunderbird calendar through CalDAV or iCalendar
project_meeting objects in Thunderbird calendar through CalDAV or iCalendar.

project_meeting object seen in Thunderbird as an event through iCalendar or CalDAV
project_meeting object seen in Thunderbird as an event through iCalendar or CalDAV.
WebDAV

The WebDAVView implements the "getTypesName", "select", "get" and "getField" methods to display the list of types, list of objects of a type, view of an object and the fields of the object in WebDAV format to be used from the HTTP/WebDAV protocol.

This view is used so that the hierarchy of types, objects, and fields can be viewed as a file system. Types and objects are viewed as folders and fields as files that can be viewed and edited with any program that can connect through WebDAV. For example you can explore the system with a file manager like Caja, edit a text field with a text editor such as Pluma or modify a document with LibreOffice.

Exploring the system with the Caja file manager and editing the "text" field of an "article_language" object with the Pluma text editor
Exploring the system with the Caja file manager and editing the "text" field of an "article_language" object with the Pluma text editor.

Document editing test with LibreOffice through WebDAV
Document editing test with LibreOffice through WebDAV.
CalDAV

The CalDAVView reimplements the WebDAV "select" method to display the list of objects of a type in CalDAV format with "getcontenttype" "text/calendar" when used the PROPFIND HTTP method and as calendar-data resources containing an iCalendar calendar when used the REPORT HTTP method. Examples are shown below:

<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus xmlns:D="DAV:">
   <D:response>
      <D:href>/project_meeting/</D:href>
         <D:propstat>
            <D:prop>
               <D:getetag/>
               <D:getcontenttype/>
            </D:prop>
               <D:status>HTTP/1.1 404 Not Found</D:status>
            </D:propstat>
            <D:propstat>
               <D:prop>
                  <D:resourcetype>
                     <calendar xmlns="urn:ietf:params:xml:ns:caldav"/>
                     <D:collection/>
                  </D:resourcetype>
               </D:prop>
               <D:status>HTTP/1.1 200 OK</D:status>
            </D:propstat>
            <D:responsedescription/>
         </D:response>
         <D:response>
            <D:href>/project_meeting/25c4b5fe-1908-11e4-8434-001eec2e2304</D:href>
            <D:propstat>
               <D:prop>
                  <D:getetag>887ed13bc8d6837f0d22108cfc27d60e</D:getetag>
                  <D:getcontenttype>text/calendar</D:getcontenttype>
                  <D:resourcetype/>
               </D:prop>
               <D:status>HTTP/1.1 200 OK</D:status>
            </D:propstat>
            <D:responsedescription/>
         </D:response>
...
<?xml version="1.0" encoding="UTF-8"?>
   <D:multistatus xmlns:D="DAV:">
      <D:response>
         <D:href>/project_meeting/44de15f9-e801-4b08-a7ce-74d724bc0629</D:href>
         <D:propstat>
            <D:prop>
               <D:getetag>be02265e4f0a1c84cf74a541c7dfd18a</D:getetag>
               <calendar-data xmlns="urn:ietf:params:xml:ns:caldav">
BEGIN:VCALENDAR
PRODID:nexttypes
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20201219T205704Z
DTSTART:20201229T170000
DTEND:20201229T200000
SUMMARY:Project 1: Meeting 8
DESCRIPTION:Meeting 8
ATTACH:https://demo.nexttypes.com:8443/project_meeting/44de15f9-e801-4b08-a7ce-74d724bc0629
UID:dd503687-4796-4517-9e42-17e19ebf02c7
END:VEVENT
END:VCALENDAR
               </calendar-data>
            </D:prop>
            <D:status>HTTP/1.1 200 OK</D:status>
         </D:propstat>
         <D:responsedescription/>
      </D:response>
...

Calendars are created with the same information as in the ICalendar view and can be viewed and edited by programs that use CalDAV.

Protocol

The protocols are modules that allow the execution of the Node, Controller and View methods through data transmission protocols. The protocols currently implemented and included in NextTypes are HTTP and SMTP.

HTTP

This implementation integrates NextTypes with the most used protocols on the Internet, allowing to integrate NextTypes with a multitude of current systems since these protocols are implemented in all web browsers, support for editing files through WebDAV is present in all operating systems and there are HTTP libraries for all programming languages.

The implementation consists of using the GET, POST and PUT HTTP methods to execute the methods defined in View and Node following a REST architecture in which all types, objects, fields of the objects and elements of the fields can be accessed through a URL and they can have different representations.

The system consists of the HTTPServlet and a series of auxiliary classes to process the requests. Its configuration is in the "http.properties" file. HTTPServlet receives all requests except for those directed to "/static", which directly access static files.

Each HTTP request instantiates a subclass of Node or View with a try-with-resources block. In this way each HTTP request corresponds to a Node transaction. In the case of a write request, if an error occurs, Node "rollback" method is automatically executed undoing the changes made.

URL

The format of the URL is as follows:

protocol://server:port/type/id/field/element?parameter1=&parameter2=

The URL is made up of the following levels:

Level Description
type Type name.
id Object identifier.
campo Object field name.
elemento Identifier of an element of an object field. For example the "id" of a "div" of an HTML field.

Different parameters can be applied to each URL that make the behavior of the system vary. NextTypes specifies some of these parameters and others can be added to the views as needed. Below is a table with the standard parameters and their description:

Parameter Description
lang ISO 639 code of the language with which you want to display the view. If the language is not specified the default language indicated in the "default_lang" configuration parameter is used.
default_lang = en
view View with which to display the resource. If not specified the default view indicated in the "default_view" parameter is used.
default_view = html
form Muestra un formulario para realizar una acción sobre el URL en el que se aplica el parámetro. Los valores válidos están indicados en la enumeración Form. Por ejemplo para mostrar el formulario de inserción de un objeto de un tipo se utiliza un URL como el siguiente:
/tipo?form=insert
View Methods

View methods are read operations, which is called in HTTP Safe Methods, and made through an HTTP GET request to a URL with the format indicated above. Each of the levels of the URL in combination with the appropriate parameters executes a method of the View class which in turn executes one or more methods of the class Node in read only mode to read the data needed to build the view and pass it to the protocol in a Content object.

The following is the list of URL addresses and their correspondence to View methods:

URL Description View Method
/ Redirects to the default index URL indicated in the "index" configuration parameter:
index = /?info
/?info System types list with information. getTypesInfo
/?names System types names list. getTypesName
/?references Lista de referencias entre tipos. getReferences
/?version References between types list. getVersion
/?form=create Type creation form. createForm
/?form=import_types Import types form. importTypesForm
/?form=import_objects Import objects form. importObjectsForm
/?form=login User session login form. loginForm
/type Type objects list. select
/type?info Type definition. getType
/type?names Type objects list with "id" and "name". getNames
/type?preview Type objects list preview. preview
/type?calendar&year=yyyy&month=mm Type objects list as a calendar. calendar
/type?filter_component=n Type objects list filter component. filterComponent
/type?component=type|reference Type objects list component. selectComponent
/type?form=alter Type alteration form. alterForm
/type?form=rename Type renaming form. renameForm
/type?form=insert Object insertion form. insertForm
/type?form=execute_action&action=action Execution form of an action from a type controller. executeActionForm
/type/id Object view. get
/type/id?form=update Formulario de actualización de objeto. updateForm
/type/id?form=update_id Object updating form. updateIdForm
/type/id?form=execute_action&action=action Execution form of an action from a type controller on the object indicated by the "id". executeActionForm
/type/id/field Object field view. getField
/type/id/field?default Type field default value. getFieldDefault
/type/id/field?form=update_password Object password field updating form. updatePasswordForm
/type/id/field/element Object field element view. getElement
Node Methods

Requests must be directed to the URL of the type or object on which the action must be applied. The POST and PUT methods are used to perform write operations, except for the export of types and objects.

In the HTTP session is stored a random string of characters that must be sent in POST requests in the "session" parameter to prevent CSRF attacks.

Requests with the POST method are in the multipart/form-data or application/x-www-form-urlencoded formats. This allows you to send the parameters from an HTML form or using any HTTP library without the need to build NextTypes objects. It is the server that is responsible for building the object.

The PUT method is used to update objects and fields by WebDAV clients. Clients can directly edit a field. They can also edit an object or field through a controller. For example a text editor can directly edit a "document" field or a calendar program update an object with an iCalendar file using a controller.

The "_action" parameter is used to indicate the method of Node or the additional action of a controller to be executed, since several actions are executed on the same URL. The "action" parameter is not used because the name conflicts with the "action" attribute of the HTML form.

In the insertion and updating of objects as well as in the execution of additional actions the names of the fields are preceded by the "@" character so that their name does not coincide with system parameters such as "_action" or "session".

Below is a list of actions, URLs and required parameters:

Action HTTP Method Description URL Parameters
create POST Type creation. / type
fields
indexes
alter POST Type alteration. /type fields
indexes
rename POST Type renaming. /type new_name
drop POST Dropping of one or more types. / types
insert POST Object insertion. /type id
type fields
update POST Object updating. /type/id type fields
PUT Object updating using the type controller. /type/id data in whatever format the controller uses
update_id POST Object identifier updating. /type/id new_id
update_password POST Object password field updating. /type/id/field current_password
new_password
new_password_repeat
update_field PUT Object field updating. /type/id/field field data
delete POST Deleting of one or more objects. /type objects
export_types POST Exporting types to a type container. If the variable "include_objects" is included it also exports the objects. / types
include_objects
export_objects POST Exporting objects to an object container. /type objects
import_types POST Importing types and their objects from a types container in the "data" parameter. The action to be carried out with the existing types and objects must be indicated. Possible actions are "abort", "alter" or "ignore" and are defined in the ImportAction enumeration. / data
existing_types_action
existing_objects_action
import_objects POST Importing objects from an object container in the "data" parameter. The action to be performed with the existing objects must be indicated. Possible actions are "abort", "update" or "ignore" and are defined in the ImportAction enumeration. /type data
existing_objects_action
Additional controller action POST Execution of an action from a type controller on several or all objects. /type objects
parameters
Execution of an action from a type controller on an object. /type/id parameters
Coding of Lists of Composite Elements.

In the creation and alteration of types it is necessary to send lists of fields and indexes that are composed of several parameters. To do this the name of each parameter consists of list name, position of the field or index within the list and the parameter name separated by ":".

list:position:parameter

For example the following shows the parameters of a type with two fields and an index.

fields:0:type
fields:0:name
fields:0:parameters
fields:0:not_null
  
fields:1:type
fields:1:name
fields:1:parameters
fields:1:not_null
  
indexes:0:mode
indexes:0:name
indexes:0:fields

Filters for objects lists are also made up of several parameters.

filters:0:field
filters:0:comparison
filters:0:value
Security

Connections are made using HTTPS. The server must have a digital certificate. When a client connects using HTTP it is redirected to use HTTPS on the port indicated in the "https_port" variable. The session cookie is set in the file WEB-INF/web.xml as "Secure" so that it is only sent over HTTPS and as "HTTP Only" so that it is not accessible from Javascript.

<session-config>
   <session-timeout>30</session-timeout>
   <cookie-config>
      <http-only>true</http-only>
      <secure>true</secure>
   </cookie-config>
</session-config>

The HTTPRequest class reads the information from the HTTP request and checks that all parameters meet system restrictions.

Authentication

Through the secure channel of the HTTPS connection the authentication of a user can be done in two ways: passwords and digital certificates. In turn password authentication can be done through the POST method or with Basic HTTP Authentication. The password is checked using the Node.checkPassword method.

When a user authenticates the system reads the groups to which he belongs with the Node.getGroups method and saves an Auth class with the user and groups in the HTTP session.

To counteract brute force attacks the system limits the number of authentication failures from the same IP address for one minute with the "max_auth_errors" configuration parameter.

max_auth_errors=5
POST Method

The HTTPServlet has two methods of logging in and logging out. As with Node the method to use is indicated by the "_action" parameter.

Action HTTP Method Description URL Parameters
login POST User session login. / login_user
login_password
logout POST User session logout. /
Digital Certificates

Clients can connect presenting a X.509 digital certificate to the server. Through objects of user_certificate type the server saves a list of the "subjects" of the certificates that allow the authentication of a user. When a user connects with a certificate the system looks for the user to whom the certificate belongs.

{
  "name" : "user_certificate",
  "cdate" : "2015-06-24T17:40:03Z",
  "adate" : "2015-06-24T17:40:03Z",
  "fields" : {
    "user" : {
      "type" : "user",
      "length" : 100,
      "not_null" : true
    },
    "certificate_subject" : {
      "type" : "string",
      "length" : 250,
      "not_null" : true
    }
  },
  "indexes" : {
    "user_certificate_subject_index" : {
      "mode" : "unique",
      "fields" : [ "certificate_subject" ]
    }
  }
}
Basic HTTP Authentication

This system is included for use by programs that cannot use the other two systems. Using the "401 Unauthorized" status code and the "WWW-Authenticate" header the client is asked to use this authentication system. The "basic_auth_realm" configuration parameter sets the name of the protection space for which authentication is required. By default NextTypes only has one space that covers the entire system.

basic_auth_realm=NextTypes

This protection space is indicated to the client in the "WWW-Authenticate" header.

WWW-Authenticate: Basic realm="NextTypes"

The "basic_auth_user_agents" variable configures the clients that are going to be asked for this type of authentication.

basic_auth_user_agents=LibreOffice,gvfs,cadaver,kioexec,Thunderbird

When one of these clients wants to carry out an action for which he needs to be authenticated and have permission he must include in the request the "Authorization" header with the username and password separated by ":" and encoded in Base64.

authorization: Basic YWRtaW46QWRtaW4jNDQ=

In Linux with the "base64" command we can decode it to see the username and password.

echo "YWRtaW46QWRtaW4jNDQ=" | base64 -d

admin:Admin#44
Limitation of Requests per Minute

To protect against denial of service attacks the number of requests per minute from the same IP address are limited. Total requests are limited by the "max_requests" parameter of "http.properties" and the maximum number of inserts of objects of a type with the "max_inserts" parameter of "types.properties".

max_requests=150
*.max_inserts=5
WebDAV

When a request is received with the PROPFIND or REPORT HTTP methods, it is processed by the view indicated in the "views.webdav" configuration parameter.

*.views.webdav=com.nexttypes.views.WebDAVView
project_meeting.views.webdav=com.nexttypes.views.CalDAVView

NextTypes includes the WebDAVView, which displays types, objects, and items such as directories and files; and the CalDAVView that displays a list of objects as calendar events. In addition other views can be created that show the objects in other formats used through WebDAV.

Reading and writing data in WebDAV is done with the GET and PUT methods that are processed by the View and Node methods.

Status Codes

For the response to the client informing the result of an action the HTTP status codes are used, together with result data or a text string describing the result:

Code Description
200 OK The action was successful.
207 Multi Status Code used to respond with a responses list to WebDAV requests.
301 Moved Permanently The "host" parameter indicates the name and domain of the system. If a request for another "host" is received the system responds with the 301 Moved Permanently code informing of the name and domain of the system to which it must connect.
host=demo.nexttypes.com
302 Found If a client accesses the root directory it is redirected to the address indicated in the "index" configuration parameter with the 302 Found code. This code is used instead of 301 because this redirection is temporary, since the value of the "index" parameter can change from time to time.
index=/?info
304 Not Modified When a view shows an object, field or element you can add an ETag header created from the object update date (udate). When requesting the client the same address again will include this header. The ViewAspect intercepts requests with the ETag header and create a new ETag tag of the requested resource. If the two tags match it indicates that the resource has not been modified, it does not need to be transferred again and an empty response can be returned with the 304 Not Modified status code.
401 Unauthorized If a user tries to perform an action for which they do not have permission the system will throw an UnauthorizedException. When HTTPServlet receives this exception it sends a response with 401 Unauthorized status code to the client. If the client must use Basic HTTP Authentication they are informed with the header "WWW-Authenticate".
404 Not Found When a type, object, field, index, element or action is not found, an NotFoundException is thrown. When HTTPServlet receives one of these exceptions, it sends to the requesting client a response with the 404 Not Found status code and the exception error message, indicating that the requested resource was not found. If the exception was thrown through a view, the "notFound" method of the view is used to format the response.
405 Method Not Allowed The only method that is allowed without using HTTPS is GET to be able to redirect the client to an HTTPS connection with 301 code. If the system receives a request through HTTP with a method other than GET it throws a MethodNotAllowedException and responds to the client with 405 Method Not Allowed status code.
429 Too Many Requests When the requests per minute limitations are exceeded the system rejects the request with a response with the 429 Too Many Requests status code.
500 Internal Server Error The action was not successful.

SMTP

The SMTPServlet partially implements a SMTP mail server with the basic functions to receive emails from a complete mail server. The server receives the email messages and converts them to raw_email objects.

{
  "name" : "raw_email",
  "cdate" : "2015-04-01T14:30:16Z",
  "adate" : "2015-04-01T14:30:16Z",
  "fields" : {
    "mail_from" : {
      "type" : "string",
      "length" : 250,
      "not_null" : true
    },
    "rcpt_to" : {
      "type" : "text",
      "not_null" : true
    },
    "data" : {
      "type" : "text",
      "not_null" : true
    }
  }
}

By creating a controller for this type it is possible to process these objects and perform actions with their data or convert them to another type.

The server is configured with the "smp.properties" file and the following configuration parameters:

Parameter Description
host Server name shown in the initial message.
220 demo.nexttypes.com NextTypes SMTP
bin_address IP address on which the server should receive connections. By default 127.0.0.1 to only receive connections from a local mail server.
port Port on which the server should receive connections. By default 2525 to not interfere with the system mail server on port 25.
backlog Maximum size of inbound connection queue used in ServerSocket class.
lang Language of error messages.

Tasks

The TasksServlet allows executing background tasks that perform different actions such as backups, scanning of virus or sending emails.

Each of the tasks is a subclass of the Task class and are added to the "tasks" parameter of the "tasks.properties" configuration file separated by commas.

tasks=com.nexttypes.system.BackupTask

Backups

NextTypes includes the BackupTask that performs incremental and full backups. In the "backup.properties" configuration file the following parameters are defined:

ParameterDescription
directoryDirectory where backup files are written.
prefixBackup file names prefix.
intervalThe time in minutes that must elapse between each backup.
incrementalNumber of incremental copies between full copies​.
langLanguage of error messages.

The backup files are types containers with the ".json" extension and have in their name the date and time when the backup was made. At the beginning of the name the prefix indicated in the variable "prefix" is added and at the end "incr" or "full" if the copy is incremental or full.

nexttypes-2021-03-29T03:15:15.294936Z-incr.json
nexttypes-2021-03-29T11:15:15.416129Z-full.json

When this task starts it analyzes the files in the directory indicated by the "directory" variable to find out how many incremental copies have been made and the date of the last one. With this information when the time indicated in the "interval" variable has passed since the last copy a new copy is made. If the number of incremental copies indicated in "incremental" has been reached a full copy is created.

To perform the incremental copy executes the node "backup" method with "full" parameter with "false" value. The node returns all the objects that have the "backup" property with "false" value, which indicates that they have not been backed up since their last update. To make a complete copy the node "backup" method is executed with "full" parameter with "true" value. In this case the node returns all the objects. Once the copy is made the "backup" property of the objects is updated to "true".

Console

NextTypes includes the Console class that allows you to perform some actions on the system from command console without using a protocol such as HTTP or the HTML graphical interface. To run it you need to go to the directory where the WAR file has been unzipped and indicate with the "-cp" parameter the location of the classes and the JAR files of the system.

With the Console "-h" parameter help is shown with the available actions and their parameters. The "-s" parameter indicates the directory where the settings we want to use to access the system are located.

cd /var/lib/tomcat9/nexttypes.com/ROOT/WEB-INF

java -cp classes:lib/* com.nexttypes.system.Console -h
usage: com.nexttypes.system.Console -b | -eo <objects> | -et <types> | -h
       | -io | -it | -vs  [-eoa <action>]  [-eta <action>] [-f]  [-ino]
       [-l <lang>] [-o <objects>] [-or <order>] [-s <settings>] [-t
       <type>]
 -b,--backup                               Backup types and objects.
 -eo,--export-objects <objects>            Export objects.
 -eoa,--existing-objects-action <action>   Existing objects action.
 -et,--export-types <types>                Export types.
 -eta,--existing-types-action <action>     Existing types action.
 -f,--full                                 Make a full backup.
 -h,--help                                 Help.
 -ino,--include-objects                    Include objects.
 -io,--import-objects                      Import objects.
 -it,--import-types                        Import types.
 -l,--lang <lang>                          Language.
 -o,--objects <objects>                    Objects Id.
 -or,--order <order>                       Query order.
 -s,--settings <settings>                  Settings directory.
 -t,--type <type>                          Type name.
 -vs,--virus-scan                          Virus scan.

For example with the "-et" parameter you can export a list of types. If no type is indicated all are exported. Adding the option "-ino" includes the objects of the types. The types are written in the "standard output" and can be redirected to a file or another program that processes the types.

java -cp classes:lib/* com.nexttypes.system.Console -s /etc/nexttypes/settings/ -et -ino > types.json

For the import of types the reverse operation is carried out, the file containing the types is redirected to the program "standard input".

java -cp classes:lib/* com.nexttypes.system.Console -s /etc/nexttypes/settings/ -it -eta abort -eoa abort < types.json

With the "-b" parameter a backup can be made. The "-f" parameter indicates that the copy is full. This allows us to make backup copies with a planning system external to the system such as "cron" or "systemd".

java -cp classes:lib/* com.nexttypes.system.Console -s /etc/nexttypes/settings/ -b > types-backup.json

The "-vs" parameter is used to scan viruses. The parameter "-t" indicates the type and the optional parameter "-o" the objects to be scanned. If the "-o" parameter is omitted all objects of the type are scanned.

java -cp classes:lib/* com.nexttypes.system.Console -s /etc/nexttypes/settings/ -vs -t example

example::test-document: Virus Found: binary -> Win.Test.EICAR_HDB-1

Creation Date:

Updating Date: