30 septembrie 2022

KOTLIN - Funcții (ziua 3)

 Functii

- pot fi standalone (in afara unei clase)

- introduse prin fun

- pot avea parametri by default

- pot extinde tipuri deja existente

- pot fi chemate din Java (import pachetul de kotlin si chemare ca functie statica)

  @file:JvmName("DisplayFunctions") // redenumire oficiala a clasei in Kotlin, pt a putea chema din Java:

  DisplayFunctions.display("ce vrei tu");


fun max(a: Int, b: Int) : Int = if (a > b) a else b // function expression
println(max(1,2))


Parametri default

@JvmOverloads // ca sa poata fi chemata din Java cu sau fara parametrul optional
// Java va crea o metoda cu un singur parametru & una cu 2 parametri
fun log(message: String, logLevel: Int = 1) {
println("$message | $logLevel")
}
log("Salut")


Denumirea parametrilor  (Java nu suporta)

- pentru a ii putea da in orice ordine si ajuta la dezambiguizare atunci cand exista mai multi parametri optionali

log(logLevel = 2, message = "Salut")


Functii care extind

Idee: adăugare funcții la clase existente -> devin funcții statice; util pentru funcții utilitare de moment.

println("Salux Pexri".replaceX())
fun String.replaceX(): String { // extinde in clasa String
return this.replace("x", "t")
}


Funcții INFIX

- prefixate cu infix, au un singur parametru

class Header(var name: String) {}

infix fun Header.plus(other: Header): Header {
return Header(this.name + " " + other.name)
}
var h1 = Header("Petri")
var h2 = Header("Mimi")
val h3 = h1 plus h2

println(h3.name) // Petri Mimi


Operator overloading

operator infix fun Header.plus(other: Header): Header {
return Header(this.name + " " + other.name)
}
val h4 = h1 + h2


Funcții foarte recursive

tailrec - cuvânt-cheie pus înainte de fun atunci când știm că vor avea loc prea multe apeluri recursive, iar Kotlin le va transforma intern într-o buclă; pentru evitarea stack overflow

29 septembrie 2022

KOTLIN - ziua 2

Fisier kt -> .class file

Rulare:

> java -cp ...\kotlin-runtime.jar MainKt 

Alta optiune: export jar

> java -jar MainKt.jar


Mai putina "ceremonie":

- poti defini clase oriunde, nu trebuie sa fie in fisier separat


STRINGS

- string interpolation: 

  println("Display $name")

  println("Display $(obj.name)")

- string comparison: if (str1 == str2)

- nullable vs non-nullable

  var answer: String// non-nullable

  var answer: String?// nullable

- string comparison with null check: if (str1?.prop == str2?.prop) // compara doar daca nu sunt nule


IF este o expresie care returneaza o valoare:

var message = if (str1 == str2) { "egal" } else { "gresit" } 


WHEN - asemanator cu switch

 when (str1) {

  "25" -> print("Corect")

  else -> print("Gresit")

}


TRY - CATCH

val num: Int = try {
Integer.parseInt("20s")
} catch (e: NumberFormatException) {
-1
}
finally {
}


Iteratii - WHILE, FOR

var range = 1..10 // inclusive
// poate fi si range = 'a'..'z' --- orice care implementeaza interfata Comparable

for (i in range step 3) {
println(i)
}
for (i in 10 downTo 1 step 4) {
println(i)
}
for (i in 1 until 10) { // non-inclusive
println(i)
}


LISTE

var nums = listOf(11,22,33)
for (i in nums) {
println(i)
}
for ((index, element) in nums.withIndex()) {
println("$element at index $index")
}


MAPS

var ages = TreeMap<String, Int>()
ages["Geo"] = 33
ages["Petri"] = 7
for ((name, age) in ages) {
println("$name's age is $age")
}

22 septembrie 2022

KOTLIN - ziua 1

KOTLIN este un limbaj OOP simplificat (cu mai puține linii de cod), care acomodează mai bine decât Java paradigma funcțională (fiind chiar limbaj funcțional) și care rulează pe JVM. Considerat o îmbunătățire a Javei.

> kotlinc hello.kt

Creează un fișier .class

> kotlinc hello.kt -include-runtime -d hello.jar

> java -jar hello.jar

Creează un jar și rulează java


var (înaintea declarării unei variabile) vs val (declară variabila immutable)

public este implicit în Kotlin

void este Unit


fun main (args: Array<String>) {
println("Hello world")

val geo = Person("Georgiana")

geo.display1()
geo.display2(::displayHelper)
}

fun displayHelper(name: String) {
println("Bravo $name")
}

class Person (var name: String) {
fun display1() {
println("Display $name")
}

fun display2 (func: (s:String) -> Unit) {
func(
name)
}
}

16 septembrie 2022

javax.validation

Un tutorial util: Spring MVC Custom Validation

Pont: se va adnota cu @Valid fiecare obiect care trebuie verificat (inclusiv in cascada, mergand pana la obiectul final ce contine adnotarea cu constrangere - cum era @ContactNumberConstraint)

--------------------------------

package secret***.controller;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class RandomValidator implements ConstraintValidator<RandomConstraint, String> {

@Override
public void initialize(RandomConstraint contactNumber) {
}

@Override
public boolean isValid(String value, ConstraintValidatorContext cxt) {
return value != null && value.matches("[0-9]+")
&& (value.length() > 8) && (value.length() < 14);
}
}
--------------------------
package secret***.controller;

import java.lang.annotation.*;

import javax.validation.Constraint;
import javax.validation.Payload;

@Documented
@Constraint(validatedBy = RandomValidator.class)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RandomConstraint {
String message() default "Invalid phone number";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
--------------------------
@PostMapping("/save")
public ResponseEntity<VrDeResultDTO> save(@RequestBody @Valid ContextDTO contextDTO) {
return new ResponseEntity<>(choreographer.save(contextDTO), HttpStatus.OK);
}
--------------------------
in ContextDTO ---> toate campurile care duc la campul adnotat cu @RandomConstraint trebuie sa aiba @Valid.

08 august 2022

Angular Architecture & Best Practices - ziua 5

Alte considerații

== înlocuire funcții cu pipes - se cheamă doar când se schimbă datele de intrare

{{ product.price | addTax | currency }}

@Pipe({

    name: 'addTax'

})

export class AddTaxPipe implements PipeTransform {

    transform(price: number): number {

        // cod 

    }

}


== Memo Decorator - ajută la caching în funcția de transform a unui pipe, când se trimite un parametru primitiv 

- dacă se repetă parametrii, ține minte rezultatul

- reies mai puține apeluri 

import memo from 'memo-decorator';

...

@memo

transform(price: number): number {

    // cod 

}


Operatori HttpClient & RxJS 

== switchMap: "switch to a new observable" -  după ce primește rezultat de la un Observable, anulează subscripția, trece la următoarea

return this.http.get(url)

         . pipe(switchMap (param1 => {

             return this.http.get(param1['param2']) // conține un url pt a obține date suplimentare

               .pipe (map (res2 => {param1['param2'] = res2; return param1;}))

      }));


== mergeMap: nu anulează inner subscripțiile, permite mai multe, nu garantează ordinea elementelor (concatMap face asta)

return this.http.get(url).pipe(switchMap (...), mergeMap (...), toArray);


== forkJoin: când toate apelurile s-au finalizat, întoarce un array cu rezultatele lor

return forkJoin (this.getA(), this.getB())

          . pipe (map ((res) => {return {val1: res[0], val2: res[1]}}));


Securitate

== CORS (Cross-origin Resource Sharing) - pe server se stabilesc domeniile/porturile de pe care poate primi request (trebuie să limiteze explicit domeniile, header-ele și metodele permise, ex. GET, POST, etc)

== CRSF (Cross-site Request Forgery) 

- pt prevenire se activează CSRF pe server dacă se folosește autentificarea prin cookie-uri 

- Angular va folosi token-ul primit în cookie-urile trimise de server pt a îl adăuga în header-ul de request (doar Angular poate face asta).

== Route Guards - OK, dar nu furnizează securitate

== Transmitere date secrete din Angular: NOK; dar se poate crea un API intermediar care să împacheteze secretul și să-l trimită la API-ul destinatar. Folosire tokeni JWT cu dată de expirare.


Interceptori HTTP

Interceptează requests / responses și atașează date în plus (ex. de tokeni de securitate).

authReq - request-ul îmbunătățit cu noi date

withCredentials - adăugat când se folosesc cookies & CORS

next.handle - predă ștafeta la următorul interceptor, dacă există


Se declară în core.module.ts.