
io.sarl.api.naming.namespace.AbstractNamespaceService.sarl Maven / Gradle / Ivy
Show all versions of api.naming Show documentation
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014-2024 SARL.io, the Original Authors and Main Authors
*
* 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
*
* http://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.
*/
package io.sarl.api.naming.namespace
import io.sarl.api.naming.name.SarlName
import io.sarl.api.naming.parser.INameParser
import org.arakhne.afc.services.AbstractService
import org.arakhne.afc.services.IService
/**
* Abstract implementation of a service that manages name spaces into the SRE.
*
* @author Stéphane Galland
* @version api.naming 0.14.0 20241106-161408
* @mavengroupid io.sarl.sdk
* @mavenartifactid api.naming
* @since 0.12
*/
abstract class AbstractNamespaceService extends AbstractService implements NamespaceService {
var nameParser : INameParser
var fieldAccessValidator : IFieldAccessValidator
override getReferenceType : Class extends IService> {
typeof(NamespaceService)
}
@Pure
override getNameParser : INameParser {
this.nameParser
}
/** Change the name parser used by this service.
*
* This function could be overloaded by sub-types in order to inject the name parser.
*
* @param parser the name parser, never {@code null}
* @since 0.11
*/
def setNameParser(parser : INameParser) {
this.nameParser = parser
}
@Pure
override getFieldAccessValidator : IFieldAccessValidator {
this.fieldAccessValidator
}
/** Change the field access validator used by this service.
*
*
This function could be overloaded by sub-types in order to inject the field access validator.
*
* @param validator the field access validator, never {@code null}
* @since 0.12
*/
def setFieldAccessValidator(validator : IFieldAccessValidator) {
this.fieldAccessValidator = validator
}
final override findObject(name : SarlName, type : Class) : T with T {
assert type !== null
var obj = findObject(name)
if (obj !== null && type.isInstance(obj)) {
return type.cast(obj)
}
return null
}
final override findObject(name : SarlName) : Object {
if (name === null) {
return null
}
var associatedObject = name.associatedObject
if (associatedObject === null) {
var obj = findObjectWithoutFragment(name)
if (obj !== null && name.hasFragment) {
// Treat the fragment
var field = obj.getDeclaredField(name)
if (field !== null) {
associatedObject = field
}
return field
} else {
try {
associatedObject = obj
} catch (ex : ClassCastException) {
//
}
}
}
return associatedObject
}
private def getDeclaredField(obj : Object, name : SarlName) : FieldAccess {
var type = obj.class
val fav = getFieldAccessValidator
if (fav !== null) {
while (type !== null && ( typeof(Object) != type )) {
try {
var field = type.getDeclaredField(name.fragment)
if (field !== null) {
val right = fav.getFieldAccessRight(obj, field)
switch (right) {
case WRITE: {
return new FieldAccess(name, field, obj, true)
}
case READ: {
return new FieldAccess(name, field, obj, false)
}
default: {
// No field
}
}
}
} catch (ex : Throwable) {
//
}
type = type.superclass
}
}
return null
}
/** Find an object with the given name, but ignoring the fragment.
*
* @param name the name of the object, never {@code null}.
* @return the object, or {@code null} if the object was not found.
*/
protected abstract def findObjectWithoutFragment(name : SarlName) : Object
}