Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .abapgit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<MIN_RELEASE>750</MIN_RELEASE>
</item>
</REQUIREMENTS>
<VERSION_CONSTANT>ZCL_URL=&gt;C_VERSION</VERSION_CONSTANT>
<VERSION_CONSTANT>/APMG/CL_URL=&gt;C_VERSION</VERSION_CONSTANT>
</DATA>
</asx:values>
</asx:abap>
73 changes: 39 additions & 34 deletions abaplint.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
"align_type_expressions": true,
"allowed_object_naming": true,
"allowed_object_types": {
"allowed": ["CLAS", "DEVC", "INTF"]
"allowed": [
"CLAS",
"DEVC",
"INTF",
"NSPC"
]
},
"ambiguous_statement": true,
"avoid_use": true,
Expand Down Expand Up @@ -164,41 +169,41 @@
"no_yoda_conditions": true,
"nrob_consistency": true,
"object_naming": {
"aqbg": "^ZABAPPM",
"aqqu": "^ZABAPPM",
"aqsg": "^ZABAPPM",
"auth": "^ZABAPPM",
"clas": "^ZC(L|X)\\_URL",
"cmod": "^ZABAPPM",
"doma": "^ZABAPPM",
"dtel": "^ZABAPPM",
"enho": "^ZABAPPM",
"enhs": "^ZABAPPM",
"enqu": "^EZABAPPM",
"form": "^ZABAPPM",
"fugr": "^ZABAPPM",
"idoc": "^ZABAPPM",
"aqbg": "^Z",
"aqqu": "^Z",
"aqsg": "^Z",
"auth": "^Z",
"clas": "^/APMG/C(L|X)_URL",
"cmod": "^Z",
"doma": "^Z",
"dtel": "^Z",
"enho": "^Z",
"enhs": "^Z",
"enqu": "^EZ",
"form": "^Z",
"fugr": "^Z",
"idoc": "^Z",
"ignoreNames": [],
"ignorePatterns": [],
"intf": "^ZIF\\_URL",
"msag": "^ZABAPPM",
"intf": "^/APMG/IF_URL",
"msag": "^Z",
"patternKind": "required",
"pinf": "^ZABAPPM",
"prog": "^ZABAPPM",
"sfpf": "^ZABAPPM",
"sfpi": "^ZABAPPM",
"shlp": "^ZABAPPM",
"ssfo": "^ZABAPPM",
"ssst": "^ZABAPPM",
"sucu": "^ZABAPPM",
"suso": "^ZABAPPM",
"sxci": "^ZABAPPM",
"tabl": "^ZABAPPM",
"tran": "^ZABAPPM",
"ttyp": "^ZABAPPM",
"wdya": "^ZABAPPM",
"wdyn": "^ZABAPPM",
"xslt": "^ZABAPPM"
"pinf": "^Z",
"prog": "^Z",
"sfpf": "^Z",
"sfpi": "^Z",
"shlp": "^Z",
"ssfo": "^Z",
"ssst": "^Z",
"sucu": "^Z",
"suso": "^Z",
"sxci": "^Z",
"tabl": "^Z",
"tran": "^Z",
"ttyp": "^Z",
"wdya": "^Z",
"wdyn": "^Z",
"xslt": "^Z"
},
"obsolete_statement": true,
"omit_parameter_name": true,
Expand Down Expand Up @@ -267,7 +272,7 @@
"xml_consistency": true
},
"syntax": {
"errorNamespace": "^(Z|Y|LCL_|TY_|LIF_)",
"errorNamespace": "^(/APMG/|LCL_|TY_|LIF_)",
"globalConstants": [],
"globalMacros": [],
"version": "v750"
Expand Down
16 changes: 16 additions & 0 deletions src/#apmg#.nspc.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_NSPC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<NSPC>
<NAMESPACE>/APMG/</NAMESPACE>
<REPLICENSE>41813564412598342476</REPLICENSE>
</NSPC>
<NSPC_TEXT>
<SPRAS>E</SPRAS>
<DESCRIPTN>apm</DESCRIPTN>
<OWNER>apm.to Inc.</OWNER>
</NSPC_TEXT>
</asx:values>
</asx:abap>
</abapGit>
59 changes: 30 additions & 29 deletions src/zcl_url.clas.abap → src/#apmg#cl_url.clas.abap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CLASS zcl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.
CLASS /apmg/cl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.

************************************************************************
* URL Object
Expand Down Expand Up @@ -36,9 +36,9 @@ CLASS zcl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.
IMPORTING
url TYPE string
RETURNING
VALUE(result) TYPE REF TO zcl_url
VALUE(result) TYPE REF TO /apmg/cl_url
RAISING
zcx_error.
/apmg/cx_error.

CLASS-METHODS default_port
IMPORTING
Expand All @@ -52,12 +52,13 @@ CLASS zcl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.
RETURNING
VALUE(result) TYPE string
RAISING
zcx_error.
/apmg/cx_error.

METHODS constructor
IMPORTING
components TYPE ty_url_components.

PROTECTED SECTION.
PRIVATE SECTION.

CLASS-METHODS is_special_scheme
Expand All @@ -70,7 +71,7 @@ CLASS zcl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.
IMPORTING
scheme TYPE string
RAISING
zcx_error.
/apmg/cx_error.

CLASS-METHODS parse_authority
IMPORTING
Expand All @@ -82,7 +83,7 @@ CLASS zcl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.
host TYPE string
port TYPE string
RAISING
zcx_error.
/apmg/cx_error.

CLASS-METHODS normalize_path
IMPORTING
Expand All @@ -106,19 +107,19 @@ CLASS zcl_url DEFINITION PUBLIC FINAL CREATE PUBLIC.
IMPORTING
address TYPE string
RAISING
zcx_error.
/apmg/cx_error.

CLASS-METHODS validate_ipv4_address
IMPORTING
address TYPE string
RAISING
zcx_error.
/apmg/cx_error.

ENDCLASS.



CLASS zcl_url IMPLEMENTATION.
CLASS /apmg/cl_url IMPLEMENTATION.


METHOD constructor.
Expand Down Expand Up @@ -196,7 +197,7 @@ CLASS zcl_url IMPLEMENTATION.
DATA components TYPE ty_url_components.

IF url IS INITIAL.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'No URL'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'No URL'.
ENDIF.

" Remove leading/trailing spaces
Expand All @@ -206,7 +207,7 @@ CLASS zcl_url IMPLEMENTATION.
" Parse scheme
DATA(delimiter) = find( val = remaining sub = ':' ).
IF delimiter < 0.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid URL: no scheme found'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid URL: no scheme found'.
ENDIF.

components-scheme = to_lower( remaining(delimiter) ).
Expand Down Expand Up @@ -305,7 +306,7 @@ CLASS zcl_url IMPLEMENTATION.
components-query = percent_decode( components-query ).
components-fragment = percent_decode( components-fragment ).

result = NEW zcl_url( components ).
result = NEW /apmg/cl_url( components ).

ENDMETHOD.

Expand Down Expand Up @@ -338,7 +339,7 @@ CLASS zcl_url IMPLEMENTATION.
" Find the closing bracket
delimiter = find( val = temp sub = ']' ).
IF delimiter < 0.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: missing closing bracket'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: missing closing bracket'.
ENDIF.

" Extract IPv6 address without brackets
Expand Down Expand Up @@ -368,21 +369,21 @@ CLASS zcl_url IMPLEMENTATION.
" Validate port if present
IF port IS NOT INITIAL.
IF NOT matches( val = port regex = '^\d+$' ).
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid port number'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid port number'.
ENDIF.
IF port NOT BETWEEN 0 AND 65535.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Port number out of range'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Port number out of range'.
ENDIF.
ENDIF.

" Validate host
IF is_special_scheme( scheme ).
IF host IS INITIAL.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Missing host'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Missing host'.
ENDIF.
ELSE.
IF host CA | \n\t\r#/:<>?@[\\]^\||.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Host contain invalid code point'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Host contain invalid code point'.
ENDIF.
ENDIF.

Expand Down Expand Up @@ -498,29 +499,29 @@ CLASS zcl_url IMPLEMENTATION.
METHOD validate_ipv4_address.

IF address IS NOT INITIAL AND address(1) = '.'.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv4 address: initial segment is empty'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv4 address: initial segment is empty'.
ENDIF.

DATA(len) = strlen( address ) - 1.
IF len >= 0 AND address+len(1) = '.'.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv4 address: last segment is empty'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv4 address: last segment is empty'.
ENDIF.

" Split by period
SPLIT address AT '.' INTO TABLE DATA(parts).

" Basic validation of IPv4 format
IF lines( parts ) <> 4.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv4 address: not four segments'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv4 address: not four segments'.
ENDIF.

" Check each part
LOOP AT parts INTO DATA(part).
IF NOT matches( val = part regex = '^\d+$' ).
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv4 address: non-numeric segment'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv4 address: non-numeric segment'.
ENDIF.
IF part NOT BETWEEN 0 AND 255.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv4 address: segment exceeds 255'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv4 address: segment exceeds 255'.
ENDIF.
ENDLOOP.

Expand All @@ -530,25 +531,25 @@ CLASS zcl_url IMPLEMENTATION.
METHOD validate_ipv6_address.

IF address(1) = ':'.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: initial piece is empty'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: initial piece is empty'.
ENDIF.

DATA(len) = strlen( address ) - 1.
IF len >= 0 AND address+len(1) = ':'.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: last piece is empty'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: last piece is empty'.
ENDIF.

" Split by colons
SPLIT address AT ':' INTO TABLE DATA(parts).

" Basic validation of IPv6 format
IF lines( parts ) > 8.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: too many pieces'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: too many pieces'.
ENDIF.

" Uncompressed addresses must have 8 parts
IF address NS '::' AND lines( parts ) <> 8.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: too few pieces'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: too few pieces'.
ENDIF.

" Check each part
Expand All @@ -558,14 +559,14 @@ CLASS zcl_url IMPLEMENTATION.
IF part IS INITIAL.
count = count + 1.
IF count > 1.
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: multiple empty pieces'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: multiple empty pieces'.
ENDIF.
CONTINUE.
ENDIF.

" Validate hexadecimal format and length
IF NOT matches( val = part regex = '^[0-9A-Fa-f]{1,4}$' ).
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid IPv6 address: invalid hexadecimal piece'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid IPv6 address: invalid hexadecimal piece'.
ENDIF.
ENDLOOP.

Expand All @@ -575,7 +576,7 @@ CLASS zcl_url IMPLEMENTATION.
METHOD validate_scheme.

IF NOT matches( val = scheme regex = '^[A-Za-z][-A-Za-z0-9+.]*' ).
RAISE EXCEPTION TYPE zcx_error_text EXPORTING text = 'Invalid scheme'.
RAISE EXCEPTION TYPE /apmg/cx_error_text EXPORTING text = 'Invalid scheme'.
ENDIF.

ENDMETHOD.
Expand Down
Loading