2020-05-13 20:14:41 +02:00
/ * *
*
2021-02-21 13:01:43 +01:00
* Copyright 2020 - 2021 Florian Schmaus
2020-05-13 20:14:41 +02:00
*
* 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 org.jivesoftware.smackx.formtypes ;
import java.util.HashMap ;
import java.util.Map ;
2021-02-21 13:01:43 +01:00
import java.util.concurrent.ConcurrentHashMap ;
import java.util.logging.Logger ;
2020-05-13 20:14:41 +02:00
import org.jivesoftware.smack.util.Objects ;
2021-02-21 13:01:43 +01:00
import org.jivesoftware.smack.util.StringUtils ;
import org.jivesoftware.smack.util.XmlUtil ;
2021-04-18 18:58:50 +02:00
2020-05-13 20:14:41 +02:00
import org.jivesoftware.smackx.xdata.FormField ;
import org.jivesoftware.smackx.xdata.TextSingleFormField ;
import org.jivesoftware.smackx.xdata.packet.DataForm ;
public class FormFieldRegistry {
2021-02-21 13:01:43 +01:00
private static final Logger LOGGER = Logger . getLogger ( FormFieldRegistry . class . getName ( ) ) ;
2020-05-13 20:14:41 +02:00
2021-02-21 13:01:43 +01:00
private static final Map < String , Map < String , FormField . Type > > REGISTRY = new HashMap < > ( ) ;
2020-05-13 20:14:41 +02:00
2021-02-21 13:01:43 +01:00
private static final Map < String , FormField . Type > CLARK_NOTATION_FIELD_REGISTRY = new ConcurrentHashMap < > ( ) ;
2020-05-13 20:14:41 +02:00
2021-03-14 17:58:13 +01:00
private static final Map < String , FormField . Type > LOOKASIDE_FIELD_REGISTRY = new ConcurrentHashMap < > ( ) ;
2020-05-13 20:14:41 +02:00
@SuppressWarnings ( " ReferenceEquality " )
2021-02-21 13:01:43 +01:00
public static void register ( DataForm dataForm ) {
2020-05-13 20:14:41 +02:00
// TODO: Also allow forms of type 'result'?
if ( dataForm . getType ( ) ! = DataForm . Type . form ) {
throw new IllegalArgumentException ( ) ;
}
String formType = null ;
TextSingleFormField hiddenFormTypeField = dataForm . getHiddenFormTypeField ( ) ;
if ( hiddenFormTypeField ! = null ) {
formType = hiddenFormTypeField . getValue ( ) ;
}
for ( FormField formField : dataForm . getFields ( ) ) {
// Note that we can compare here by reference equality to skip the hidden form type field.
if ( formField = = hiddenFormTypeField ) {
continue ;
}
FormField . Type type = formField . getType ( ) ;
2021-02-21 13:01:43 +01:00
if ( type = = FormField . Type . fixed ) {
continue ;
}
String fieldName = formField . getFieldName ( ) ;
2020-05-13 20:14:41 +02:00
register ( formType , fieldName , type ) ;
}
}
2021-12-15 20:14:18 +01:00
public static void register ( String formType , FormField . Type fieldType , String . . . fieldNames ) {
for ( String fieldName : fieldNames ) {
register ( formType , fieldName , fieldType ) ;
}
}
2021-02-21 13:01:43 +01:00
public static void register ( String formType , String fieldName , FormField . Type fieldType ) {
StringUtils . requireNotNullNorEmpty ( fieldName , " fieldName must be provided " ) ;
Objects . requireNonNull ( fieldType ) ;
2020-05-13 20:14:41 +02:00
2021-02-21 13:01:43 +01:00
if ( formType = = null ) {
if ( XmlUtil . isClarkNotation ( fieldName ) ) {
CLARK_NOTATION_FIELD_REGISTRY . put ( fieldName , fieldType ) ;
2020-05-13 20:14:41 +02:00
}
return ;
}
2021-02-21 13:01:43 +01:00
FormField . Type previousType ;
synchronized ( REGISTRY ) {
Map < String , FormField . Type > fieldNameToType = REGISTRY . get ( formType ) ;
if ( fieldNameToType = = null ) {
fieldNameToType = new HashMap < > ( ) ;
REGISTRY . put ( formType , fieldNameToType ) ;
} else {
previousType = fieldNameToType . get ( fieldName ) ;
if ( previousType ! = null & & previousType ! = fieldType ) {
throw new IllegalArgumentException ( ) ;
}
2020-05-13 20:14:41 +02:00
}
2021-02-21 13:01:43 +01:00
previousType = fieldNameToType . put ( fieldName , fieldType ) ;
}
if ( previousType ! = null & & fieldType ! = previousType ) {
LOGGER . warning ( " Form field registry inconsitency detected: Registered field ' " + fieldName + " ' of type " + fieldType + " but previous type was " + previousType ) ;
2020-05-13 20:14:41 +02:00
}
}
2021-02-21 13:01:43 +01:00
public static FormField . Type lookup ( String formType , String fieldName ) {
if ( formType = = null ) {
2021-03-14 17:58:13 +01:00
if ( XmlUtil . isClarkNotation ( fieldName ) ) {
return CLARK_NOTATION_FIELD_REGISTRY . get ( fieldName ) ;
2020-05-13 20:14:41 +02:00
}
2021-03-14 17:58:13 +01:00
return LOOKASIDE_FIELD_REGISTRY . get ( fieldName ) ;
2021-02-21 13:01:43 +01:00
}
2020-05-13 20:14:41 +02:00
2021-02-21 13:01:43 +01:00
synchronized ( REGISTRY ) {
2020-05-13 20:14:41 +02:00
Map < String , FormField . Type > fieldNameToTypeMap = REGISTRY . get ( formType ) ;
if ( fieldNameToTypeMap ! = null ) {
FormField . Type type = fieldNameToTypeMap . get ( fieldName ) ;
if ( type ! = null ) {
return type ;
}
}
}
2021-02-21 13:01:43 +01:00
return null ;
2020-05-13 20:14:41 +02:00
}
2021-02-21 13:01:43 +01:00
public static synchronized FormField . Type lookup ( String fieldName ) {
return lookup ( null , fieldName ) ;
2020-05-13 20:14:41 +02:00
}
2021-03-14 17:58:13 +01:00
public static void addLookasideFieldRegistryEntry ( String fieldName , FormField . Type formFieldType ) {
LOOKASIDE_FIELD_REGISTRY . put ( fieldName , formFieldType ) ;
}
2020-05-13 20:14:41 +02:00
}