Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gerrit Alexander Simon Evers
Verteilte Systeme Projekt
Commits
cb2f92ba
Commit
cb2f92ba
authored
Feb 09, 2021
by
Andre Blanke
Browse files
Implement support for custom ids
parent
6852ff0c
Changes
6
Hide whitespace changes
Inline
Side-by-side
shortener/src/main/angular/shortener/src/app/shortener-form.component.ts
View file @
cb2f92ba
import
{
Component
}
from
"
@angular/core
"
;
import
{
HttpClient
,
HttpHeaders
,
HttpParams
}
from
"
@angular/common/http
"
;
import
{
HttpClient
,
HttpHeaders
,
HttpParams
}
from
"
@angular/common/http
"
;
class
ShortenerFormModel
{
url
:
string
=
""
id
:
string
=
""
}
@
Component
({
selector
:
'
shortener-form
'
,
template
:
`
<form id="shortener-form" (ngSubmit)="submit()" method="post">
<input id="long-url-input" name="url" type="text" placeholder="Enter a long URL" [(ngModel)]="model.url">
<button type="submit">Shorten URL</button>
<ul>
<li>
<input id="long-url-input" name="url" type="text" placeholder="Enter a long URL"
title="The URL to be shortened" [(ngModel)]="model.url">
</li>
<li>
<p>and optionally specify a custom id:</p>
</li>
<li>
<input id="short-url-id-input" name="id" type="text" placeholder="optionally enter a custom id"
pattern="[a-zA-Z0-9]+" title="Custom id for the short URL" [(ngModel)]="model.id">
<button type="submit">Shorten URL</button>
</li>
</ul>
</form>
<div id="shortener-form-output">
<label id="short-url-label" for="short-url">
Y
our short URL:</label>
<label id="short-url-label" for="short-url">
Click to copy y
our short URL:</label>
<input id="short-url-output" name="short-url" (click)="copyContent($event)" readonly/>
</div>
`
...
...
@@ -29,9 +42,10 @@ export class ShortenerFormComponent {
const
headers
=
new
HttpHeaders
()
.
set
(
"
Content-Type
"
,
"
application/x-www-form-urlencoded
"
)
const
body
=
new
HttpParams
()
.
append
(
"
url
"
,
encodeURIComponent
(
this
.
model
.
url
));
let
body
=
new
HttpParams
().
append
(
"
url
"
,
encodeURIComponent
(
this
.
model
.
url
));
if
(
this
.
model
.
id
!==
""
)
body
=
body
.
append
(
"
id
"
,
this
.
model
.
id
.
toLowerCase
());
this
.
http
.
post
(
"
http://upbshrt.xyz/
"
,
body
,
{
headers
:
headers
,
responseType
:
"
text
"
})
...
...
@@ -43,7 +57,10 @@ export class ShortenerFormComponent {
(
document
.
getElementById
(
"
short-url-output
"
)
as
HTMLInputElement
)
.
value
=
decodeURIComponent
(
data
);
},
error
=>
console
.
log
(
error
));
error
=>
{
console
.
log
(
error
);
alert
(
error
.
message
);
});
}
copyContent
(
event
:
MouseEvent
):
void
{
...
...
shortener/src/main/angular/shortener/src/styles.css
View file @
cb2f92ba
...
...
@@ -23,12 +23,22 @@ html {
justify-content
:
center
;
}
#long-url-input
{
#shortener-form
>
ul
{
list-style
:
none
;
padding
:
0
;
margin
:
0
;
}
#short-url-id-input
{
margin-right
:
10px
;
}
#short-url-id-input
:invalid
{
color
:
red
;
}
#shortener-form-output
{
margin-top
:
1
0px
;
margin-top
:
5
0px
;
visibility
:
hidden
;
}
...
...
shortener/src/main/kotlin/xyz/upbshrt/shortener/controller/UrlShorteningController.kt
View file @
cb2f92ba
...
...
@@ -4,6 +4,7 @@ import java.net.URI
import
java.net.URLDecoder
import
java.net.URLEncoder
import
java.nio.charset.StandardCharsets
import
java.math.BigInteger
import
javax.validation.constraints.Pattern
...
...
@@ -68,7 +69,8 @@ class UrlShorteningController @Autowired constructor(private val repository: Url
)
}
val
numericId
:
Int
?
=
id
?.
toInt
(
UrlMapping
.
ID_RADIX
)
val
numericId
:
BigInteger
?
=
if
(
id
!=
null
)
BigInteger
(
id
,
UrlMapping
.
ID_RADIX
)
else
null
if
((
numericId
!=
null
)
&&
repository
.
existsById
(
numericId
))
throw
ResponseStatusException
(
HttpStatus
.
UNPROCESSABLE_ENTITY
,
...
...
@@ -95,8 +97,8 @@ class UrlShorteningController @Autowired constructor(private val repository: Url
*/
@GetMapping
(
"/{id:^[a-z0-9]+$}"
)
fun
resolveUrl
(
@PathVariable
id
:
String
):
ResponseEntity
<
Nothing
>
{
val
numericId
:
Int
=
try
{
id
.
toInt
(
UrlMapping
.
ID_RADIX
)
val
numericId
:
BigInteger
=
try
{
BigInteger
(
id
,
UrlMapping
.
ID_RADIX
)
}
catch
(
exception
:
NumberFormatException
)
{
handleMalformedId
(
id
)
}
...
...
shortener/src/main/kotlin/xyz/upbshrt/shortener/entity/UrlMapping.kt
View file @
cb2f92ba
package
xyz.upbshrt.shortener.entity
import
java.math.BigInteger
import
javax.persistence.Column
import
javax.persistence.Entity
import
javax.persistence.Id
import
javax.persistence.GeneratedValue
import
javax.persistence.GenerationType
import
javax.persistence.SequenceGenerator
import
org.hibernate.annotations.GenericGenerator
import
org.hibernate.annotations.Parameter
import
org.hibernate.id.enhanced.SequenceStyleGenerator
@Entity
class
UrlMapping
(
id
:
Int
?,
url
:
String
)
{
class
UrlMapping
(
id
:
BigInteger
?,
url
:
String
)
{
@Id
@Suppress
(
"CanBePrimaryConstructorProperty"
)
@GeneratedValue
(
strategy
=
GenerationType
.
SEQUENCE
,
generator
=
"UrlMappingIdSequence"
)
@SequenceGenerator
(
name
=
"UrlMappingIdSequence"
,
sequenceName
=
"url_mapping_id_sequence"
,
allocationSize
=
1
@GenericGenerator
(
name
=
"UrlMappingIdSequence"
,
strategy
=
"xyz.upbshrt.shortener.hibernate.SequenceStyleGenerator"
,
parameters
=
[
Parameter
(
name
=
SequenceStyleGenerator
.
DEF_SEQUENCE_NAME
,
value
=
"url_mapping_id_sequence"
),
Parameter
(
name
=
SequenceStyleGenerator
.
INCREMENT_PARAM
,
value
=
"1"
)
]
)
private
var
id
:
Int
?
=
id
private
var
id
:
BigInteger
?
=
id
@Column
(
length
=
2048
,
nullable
=
false
)
var
url
:
String
=
url
...
...
shortener/src/main/kotlin/xyz/upbshrt/shortener/hibernate/SequenceStyleGenerator.kt
0 → 100644
View file @
cb2f92ba
package
xyz.upbshrt.shortener.hibernate
import
java.io.Serializable
import
java.util.Properties
import
org.hibernate.MappingException
import
org.hibernate.engine.spi.SharedSessionContractImplementor
import
org.hibernate.service.ServiceRegistry
import
org.hibernate.type.Type
/**
* Overrides Hibernate's default [org.hibernate.id.enhanced.SequenceStyleGenerator] to add support for manually
* assigned ids.
*/
class
SequenceStyleGenerator
:
org
.
hibernate
.
id
.
enhanced
.
SequenceStyleGenerator
()
{
lateinit
var
entityName
:
String
override
fun
configure
(
type
:
Type
?,
params
:
Properties
,
serviceRegistry
:
ServiceRegistry
?)
{
entityName
=
params
.
getProperty
(
ENTITY_NAME
)
?:
throw
MappingException
(
"no entity name"
)
super
.
configure
(
type
,
params
,
serviceRegistry
)
}
override
fun
generate
(
session
:
SharedSessionContractImplementor
,
`object`
:
Any
?):
Serializable
=
session
.
getEntityPersister
(
""
,
`object`
)
.
getIdentifier
(
`object`
,
session
)
?:
super
.
generate
(
session
,
`object`
)
}
shortener/src/main/kotlin/xyz/upbshrt/shortener/repository/UrlMappingRepository.kt
View file @
cb2f92ba
package
xyz.upbshrt.shortener.repository
import
java.math.BigInteger
import
org.springframework.data.jpa.repository.JpaRepository
import
org.springframework.stereotype.Repository
import
xyz.upbshrt.shortener.entity.UrlMapping
@Repository
interface
UrlMappingRepository
:
JpaRepository
<
UrlMapping
,
Int
>
interface
UrlMappingRepository
:
JpaRepository
<
UrlMapping
,
BigInteger
>
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment