08 iulie 2020

Pași pentru folosire branch itrac

> git checkout -b feature/itrac-11111 master  -- crearea unui branch nou cu id-ul de pe itrac, din master
> git add .
> git commit -m "itrac-11111 your message"
> git push --set-upstream origin feature/itrac-11111

Bitbucket -> Repositories -> navigare repo corespunzător -> Branches -> Pull request

01 iulie 2020

Validare xml cu xsd in Java

private static void initialize() throws SAXException { 
    final SchemaFactory factory = 
        SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
    final InputStream xsdStream = XmlDocumentValidator.class.getClassLoader()
        .getResourceAsStream(SCHEMA_PATH);            
    final Schema schema = factory.newSchema(new StreamSource(xsdStream)); 
    validator = schema.newValidator();      
    validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); 
    validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); 

public static boolean validateSchema(Resource resource) { 
    try (InputStream inputStream = resource.getInputStream()) { 
        if (validator == null) { 
            initialize(); 
        } 
        validator.validate(new StreamSource(inputStream)); 
        return true; 
    } catch (final SAXException | IOException e) { 
        LOGGER.error("Schema validation failed", e); 
        return false; 
    } 
}

26 iunie 2020

Reveng tool pentru actualizarea claselor java corelate cu baza de date

1. modificare hibernate-reveng.xml, adaugare declaratii:
<schema-selection match-schema="SCHEMA_NAME" match-table="TABLE_NAME" />
<table name="TABLE_NAME" schema="SCHEMA_NAME">
  <primary-key>
    <key-column name="PK_COLUMN_NAME" />
  </primary-key>
</table>

2. Realizarea conexiunii cu BD (hibernate.properties)
hibernate.connection.driver_class=oracle.jdbc.OracleDriver
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.connection.url=jdbc:oracle:thin:@//URL:PORT/DB_NAME
hibernate.connection.username=OWNER
hibernate.connection.password=PASS

3. Rularea plugin-ului
> mvn clean generate-sources -P reveng

4. Commit fisiere modificate, punctual

15 aprilie 2020

Obtinerea resurselor de test in Java

Presupunem un director cu calea: src/test/resources/fileprocessor/source

1. ClassLoader:

final String SOURCE_PATH = "fileprocessor/source";
sourceFolder = new File(this.getClass().getClassLoader().getResource(SOURCE_PATH).getFile());


2. Obtinerea caii relativ la proiect:

private static final String SOURCE_PATH = "./target/test-classes/fileprocessor/source";
sourceFolder = new File(SOURCE_PATH);
P.S. Nu folosim pe Bamboo file.getAbsolutePath() !!!

11 aprilie 2020

Angular - ziua 10 - Componente dinamice

Componente dinamice - sunt create la runtime, momentul cand vor trebui sa fie afisate este controlat programatic, cu *ngIf sau cu Dynamic Component Loader

Dynamic Component Loader: componenta este adaugata la DOM prin cod (imperativ) (vs. declarativ, printr-un selector, la *ngIf)
Totusi, varianta prin *ngIf este mai usoara si cea recomandata.

Exemplu cu *ngIf pentru afisarea unei ferestre de eroare:

1. se creeaza o componenta noua, numita de exemplu AlertComponent, cu satelitii aferenti, si se importa in app.module.ts langa celelalte componente.
@Component({
  selector: 'app-alert',
  templateUrl: './alert.component.html',
  styleUrls: ['./alert.component.css']
})

2. In componenta se adauga:
@Input() message: string; // string settable from outside
@Output() closeEvent = new EventEmitter<void>(); // emits on onClose() for the outside

3. In Html, fereastra de alerta are un buton cu textul "Close", se adauga: (click)="onClose()" pentru a declansa emitter-ul din Typescript.

4. Componenta de alert este folosita in componenta din care vrem s-o chemam, cu *ngIf, trimitandu-i drept input [message] o variabila, iar pe output-ul (closeEvent) devenit input in acea componenta, se merge pe o metoda onHandleError din componenta curenta:
<app-alert [message]="error" *ngIf="error" (closeEvent)="onHandleError()"></app-alert>

5. In onHandleError() avem grija sa schimbam conditiile pentru care *ngIf este true, deci putem seta this.error = null acolo.

----

Varianta programatica ( mai grea, pentru acelasi scenariu )

1. Se creeaza o componenta noua, adnotata cu @Directive, care va reprezenta definitia unui obiect in DOM (de fapt gata sa fie introdus in DOM). ViewContainerRef reprezinta "un container unde se pot adauga una sau mai multe view-uri la componenta"

@Directive({
  selector: '[appPlaceholder]'})
export class PlaceholderDirective {
  constructor(public viewContainerRef: ViewContainerRef) {
  }
}

2. In Html-ul componentei unde vrem sa atasam componenta dinamica, declaram (este doar o declaratie, nu apare in DOM):
<ng-template appPlaceholder></ng-template> 

3. In TypeScript-ul componentei de mai sus vom realiza adaugarea programatica. Dar intai declaram variabilele clasei:
@ViewChild(PlaceholderDirective) alertHost: PlaceholderDirective;
private closeSub: Subscription;

4. Se injecteaza in constructor: private componentFactoryResolver: ComponentFactoryResolver

Intr-o metoda de showErrorAlert():
5. Se obtine din alertHost proprietatea de tipul ViewContainerRef declarata, se face clear() pe ea

6. Din "fabrica" de componente se obtine sub-fabrica de tipul AlertComponent:
const alertCompFactory = this.componentFactoryResolver.resolveComponentFactory(AlertComponent);

7. Se creeaza componenta dinamica cu ajutorul ei si se populeaza campul message cu ceva ce ar trebui sa primim ca parametru in metoda:
const componentRef = hostViewContainerRef.createComponent(alertCompFactory);
componentRef.instance.message = errorResponse;

8. Se face subscribe pe pe proprietatea closeEvent a componentei, care se salveaza intr-o subscriptie:
this.closeSub = componentRef.instance.closeEvent.subscribe(() => {
  this.closeSub.unsubscribe();
  hostViewContainerRef.clear();
});

Asadar, cand se apasa pe "Close", subscriptia in curs se termina, iar componenta se "curata" astfel disparand de pe ecran.

9. Metoda de mai sus este chemata pe ramura de tratare a erorii dupa login/logout.