VU+ DUO Enigma2 - informacja o portach

, poniedziałek, 30 lipca 2012 0 komentarze

Ostatnio zostałem użytkownikiem sprzętu o nazwie VU+ DUO będącego tunerem telewizji satelitarnej opartym na systemie LINUX. Wszystkim tym którzy chcą mieć naprawdę dobrą maszynę z ładnym interfejsem graficznym (tutaj zachęcam do zainstalowania Black Hole) do oglądania telewizji SAT polecam ten sprzęt.

Przestrzegam wszystkich na wstępie przed tworzeniem hasła zawierającego znak AT (@) ponieważ ja takowe miałem i było to źródłem problemów ze steamingiem na iPAD-a i na inne urządzenia również. Pojawiający się błąd na iPAD w ogóle nic nie mówi na temat problemu z URL-em i dlatego ta przestroga - pół dnia na to straciłem żeby stwierdzić gdzie leży przyczyna.

No to teraz wyjaśnienie na temat otwartych portów:

21 - FTP
22 - SSH
23 - Telnet
80 - WebInterface - można zmienić w ustawieniach pluginu (polecam to zrobić - można uniknąć wielu problemów jak zainstaluje się nam inna wtyczka pracująca na porcie 80 i zrestartujemy system)
111 -
139 - Netbios port
445 - port wymiany plików Windows (SMB)
2029 -
8001 - domyślny port streamingu VIDEO
12000 - port nasłuchu serwera CCcam (można wyłączyć nasłuch ustawiając parametr "SERVER LISTEN PORT" na 0 w pliku /etc/CCcam.conf)
16000 - port telnetu dla CCcam
16001 - port usługi WEB dla CCcam: http://ip_CCcam_server:16001
31335 - STREAM-SEC: przeznaczenie to wysyłanie pojedynczego strumienia - wykorzystywany do strumieniowania AUDIO MP2
31337 -
31338 - STREAM-PES: przeznaczenie to strumieniowanie DVB zawierające kilka ES wewnątrz
31339 - STREAM-TS: przeznaczenie to strumieniowanie DVB z wykorzystaniem transport-stream jako kontenera
31340 - UDP-STREAM-PES
31341 - UDP-STREAM-PES
31342 - STREAM-TS-FILE: przeznaczenie to strumieniowanie DVB - odczyt z pliku zamiast z demultipleksera
31343 - STREAM-ES
57076 -
60533 -



SmartGWT: zamknięcie okna po operacji saveData()

, niedziela, 31 lipca 2011 0 komentarze

Przedstawiam rozwiązanie problemu dotyczącego zamknięcia okna po poprawnym wykonaniu operacji save. Problem polega na tym, że po wykonaniu kodu jak poniżej dostaniemy błąd NULL-owej referencji do okna.

public class DynamicFormWindow extends Window {
protected DynamicForm form;
private ActionPanel actionPanel = new ActionPanel();

public DynamicFormWindow(DynamicForm form, String title) {
this.form = form;

setShowShadow(true);
setShadowSoftness(4);
setShadowOffset(3);

this.setTitle(title);
this.setLayoutMargin(4);
this.setShowMinimizeButton(false);
this.setCanDragResize(true);
this.setAutoSize(true);
this.setIsModal(true);
this.setShowModalMask(false);
this.centerInPage();

this.addCloseClickHandler(new CloseClickHandler() {
@Override
public void onCloseClick(CloseClientEvent event) {
destroy();
}
});

VPanel panel = new VPanel();
panel.setPadding(2);
panel.addMember(form);
panel.addMember(this.actionPanel);

this.addItem(panel);

IButton saveButton = new IButton("Zapisz");
saveButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
DynamicFormWindow.this.saveData();
}
});
addActionButton(saveButton);
}

protected void saveData() {
this.form.saveData();
this.destroy();
}

protected void addActionButton(IButton button) {
this.actionPanel.addMember(button);
}

}


Problem polega na tym, że po wykonaniu saveData() automatycznie wykonywane jest destroy(), gdzie saveData() wykonuje akcję asynchronicznie używając GWT-RPC po stronie serwerowej aplikacji.

Rozwiązaniem problemu jest wykorzystanie Callbacka na saveData() oraz funkcjonalności Scheduler-a. W tym celu zmieniamy ciało metody saveData() w następujący sposób:


protected void saveData() {
if (this.form.validate()) {
this.form.saveData(new DSCallback() {
@Override
public void execute(DSResponse response, Object rawData, DSRequest request) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
DynamicFormWindow.this.destroy();
}
});
}
});
}
}


Takie podejście daje nam to, że kod zamykający okno wykonywany jest po tym jak zakończy się operacja saveData() oraz bieżąca pętla obsługi zdarzeń GWT. Oznacza to, że kod zamykający okno wykona się po całkowitym zakończeniu obsługi związanej z akcją saveData().

Dodatkowe metody Schedulera scheduleEntry/scheduleFinally wykonywane są wewnątrz pętli obsługi zdarzeń zaraz przed/po tym jak wykonany zostanie kod związany z obsługą zdarzeń GWT. W przypadku wykonywania manipulacji DOM wewnątrz tej samej pętli obsługi zdarzeń, można przeciwdziałać dodatkowemu odmalowaniu przez browser.

Web Project Template, czyli Eclipse + Maven+ Spring + GWT + Hibernate

, , , , 0 komentarze

W tym artykule chciałbym podzielić się swoim doświadczeniem w ramach konfiguracji projektu typu Web wykorzystującego Spring, SmartGWT, Hiberante. Całość konfiguracji w zamierzeniu ma być budowana przez Maven-a. Zakładam, że do developmentu używane będzie środowisko Eclipse Helios SR 2. Dlatego zacznijmy od konfiguracji środowiska projektowego.

Zaczynamy od ściągnięcia Eclipsa ze strony Eclipse Helios SR2 Packages (v 3.6.2). Teraz, żeby nam się dobrze pracowało instalujemy następujące pluginy:
- Maven Integration for Eclipse Update Site
- Google Update Site for Eclipse 3.6
- GWT Designer Update Site
- SpringSource Update Site for Eclipse 3.6
- SpringSource Update Site for Eclipse 3.6 (Dependencies)
- JBoss Tools Development Milestone Update Site
Po instalacji Eclipse oraz wymienionych pluginów jesteśmy przygotowani do pracy, więc możemy zacząć. Moja propozycja podziału na moduły aplikacji typu Web jest następująca:
- moduł dziedzinowy: zawierający zarówno model dziedzinowy jak i operacje związane z modelem, czyli inaczej mówiąc model JPA oraz związane z nimi DAO (Data Access Objects)
- moduł usług: zawierający bean-y Springowe udostępniające usługi biznesowe w oparciu o model dziedzinowy
- moduł warstwy web: moduł zawierający całość logiki klienckiej, udostępniający warstwę UI dla użytkownika końcowego.

Moduł warstwy web komunikuje się z modułem serwisów w celu wykonywania akcji po stronie serwera. Nie ma on dostępu do modułu domenowego, gdyż moduł serwisów izoluje dostęp do warstwy domenowej.

Zajmijmy się teraz konfiguracją modułów. W tym celu utworzyć należy strukturę plików tak jak zostało to przedstawione na rysunku obok.

Najważniejsze w tym momencie są pliki pom.xml, czyli pliki konfiguracyjne Mavena. Teraz zajmę się ustawieniami w tych plikach. Dobrze, główny plik konfiguracyjny (root) znajdujący się na poziomie katalogów m2-domain, m2-service, m2-web wygląda następująco:

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0
pl.masl.m2
m2-root
1.0.0-SNAPSHOT
pom
M-2 :: ${project.artifactId}


UTF-8
1.6
1.6
4.8.2
3.0.5.RELEASE
3.0.5.RELEASE
3.5.6-Final
1.0.0.Final
2.0.8
5.1.10



m2-domain
m2-service
m2-web




junit
junit
${junit.verion}
test


org.slf4j
jcl-over-slf4j
1.5.8


org.slf4j
slf4j-log4j12
1.5.8





maven-annotation-plugin

http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo






Central Repo
http://repo1.maven.org/maven2


com.springsource.repository.maven.release
http://maven.springframework.org/release/

false



com.springsource.repository.maven.snapshot
http://maven.springframework.org/snapshot/

true



com.springsource.repository.maven.milestone
http://maven.springframework.org/milestone/

false



SmartGWT Repo
http://www.smartclient.com/maven2/


JavaNet
http://download.java.net/maven/2




Co widać w tym pliku to ustawienia dotyczące wersji bibliotek używanych w ramach aplikacji, definicję modułów z których składa się aplikacja oraz definicja repozytoriów dla bibliotek.

Następnie konfigurujemy plik pom.xml dla modułu domenowego:
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0


m2-root
pl.masl.m2
1.0.0-SNAPSHOT


pl.masl.m2
m2-domain
1.0.0-SNAPSHOT
M-2 :: ${project.artifactId}



org.hibernate
hibernate-jpamodelgen
${hibernate-jpa.version}


org.hibernate
hibernate-entitymanager
${hibernate.version}


org.hibernate
hibernate-c3p0
${hibernate.version}


org.hibernate
hibernate-ehcache
${hibernate.version}


org.springframework
spring-test
${spring.version}


org.springframework.data
spring-data-jpa
1.0.0.M2


org.springframework
spring-orm
${spring.version}


mysql
mysql-connector-java
${mysql.connector.version}






org.apache.maven.plugins
maven-compiler-plugin
2.0.2

${maven.compiler.source}
${maven.compiler.target}
${project.build.sourceEncoding}
-proc:none




org.bsc.maven
maven-processor-plugin
1.3.1


process

process

generate-sources

target/metamodel


org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor








org.codehaus.mojo
build-helper-maven-plugin
1.3


add-source
generate-sources

add-source



target/metamodel










Co mamy w tym pliku to zależności od hibernate-a i Springa, definicja pluginu do kompilacji, definicja pluginów do generacji modelu JPA 2.0.

Teraz konfiguracja pliku pom.xml dla modułu usług:
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0

m2-root
pl.masl.m2
1.0.0-SNAPSHOT

pl.masl.m2
m2-service
1.0.0-SNAPSHOT
M-2 :: ${project.artifactId}



pl.masl.m2
m2-domain
1.0.0-SNAPSHOT
jar
compile


aspectj
aspectjrt
1.5.4


aspectj
aspectjweaver
1.5.4


net.sf.dozer
dozer
5.3.2


org.springframework
spring-tx
${spring.version}


org.springframework.security
spring-security-config
${springframework.security.version}






org.apache.maven.plugins
maven-compiler-plugin
2.3.2

${maven.compiler.source}
${maven.compiler.target}
${project.build.sourceEncoding}



org.apache.maven.plugins
maven-source-plugin
2.1.2


attach-sources
verify

jar-no-fork








W tym pliku widać definicję zależności od modułu domenowego, bibliotek Springa oraz pluginów do kompilacji.

No i na koniec definicja pom.xml-a dla modułu webowego:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">


m2-root
pl.masl.m2
1.0.0-SNAPSHOT


4.0.0
pl.masl.m2
m2-web
war
1.0.0-SNAPSHOT
M-2 :: ${project.artifactId}



2.3.0
2.4
${project.build.directory}/${project.build.finalName}




pl.masl.m2
m2-service
1.0.0-SNAPSHOT


com.google.gwt
gwt-user
${gwtVersion}
provided


com.google.gwt
gwt-servlet
${gwtVersion}
compile


javax.validation
validation-api
1.0.0.GA
test


javax.validation
validation-api
1.0.0.GA
sources
test


com.smartgwt
smartgwt
${smartgwt.version}
compile


com.smartgwt
smartgwt-skins
${smartgwt.version}
compile


com.google.code
gwt-log
3.1.3


net.sf.gwt-widget
gwt-sl
1.3-RC1
jar
compile


gwt-servlet
com.google.gwt


cglib-nodep
cglib




org.springframework
spring-web
${spring.version}


org.springframework
spring-webmvc
${spring.version}



org.springframework.security
spring-security-config
${springframework.security.version}


org.springframework.security
spring-security-web
${springframework.security.version}




${webappDirectory}/WEB-INF/classes
m2



org.codehaus.mojo
gwt-maven-plugin
2.3.0-1



compile
test
i18n
generateAsync





pl.masl.m2:m2-service

M2.html
${webappDirectory}
pl.masl.m2.web.gwt.client.Constants


pl.masl.m2.web.gwt.client.Messages




org.apache.maven.plugins
maven-war-plugin
2.1.1


compile

exploded




${webappDirectory}



org.apache.maven.plugins
maven-compiler-plugin
2.3.2

${maven.compiler.source}
${maven.compiler.target}
${project.build.sourceEncoding}






Tutaj mamy uzależnienie od bibliotek Springa, bibliotek GWT, bibliotek SmartGWT, ustawień dla kompilacji GWT oraz ustawień dla modułu typu WEB.

Teraz zajmiemy się wciągnięciem modułów do Eclipsa.

Obsługa DTO dla Spring i SmartGWT

, , 0 komentarze

Ostatnio miałem problem z przekazywaniem informacji pomiędzy częścią serwerową aplikacji opartą o serwisy w postaci bean-ów Spring oraz częścią kliencką przygotowaną w formie aplikacji SmartGWT. Problem polegał na tym, że miałem dosyć dużo obiektów domenowych JPA i żeby wymieniać informacje z aplikacją kliencką przy standardowym podejściu musiałbym napisać dla każdej klasy obiektu domenowego klasę DTO. Stwierdziłem, że to strasznie dużo roboty i zacząłem się zastanawiać jak sobie ułatwić życie i zrobić to jakimś automatem. Wpadłem na pomysł przesyłania informacji w postaci tzw. dynamic property i zrobiłem pod to implementację, którą chciałbym się w tym momencie podzielić.

Pomysł polega na tym, aby zarówno po stronie serwerowej jak i klienckiej napisać serializer i deserailzer dynamic property. Rozpocząłem od napisania adnotacji, która ma zasięg metody i służyć będzie do oznaczenie getterów dla property przesyłanych na stronę serwerową i na odwrót. Adnotacja taka ma następującą postać:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DynamicDataProperty {

boolean embeded() default false;
}


No dobrze mamy adnotację to teraz oznaczmy przy jej użyciu odpowiednie obiekty domenowe. Załóżmy, że mamy obiekt domenowy Customer, który wykorzystuje zanurzony obiekt Address tak jak poniżej.

@javax.persistence.Entity
@Table(name = "customers")
public class Customer extends EntityObject {
private static final long serialVersionUID = -5104067194504977189L;

@Column(name = "code", unique = true, nullable = false, length = 60)
private String code;

@Column(name = "name", unique = false, nullable = false, length = 255)
private String name;

@Column(name = "discount", unique = false, nullable = false)
private short discount;

@Embedded
private Address address = new Address();

@DynamicDataProperty
public String getCode() {
return this.code;
}

public void setCode(String code) {
this.code = code;
}

@DynamicDataProperty
public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

@DynamicDataProperty
public short getDiscount() {
return this.discount;
}

public void setDiscount(short discount) {
this.discount = discount;
}

@DynamicDataProperty(embeded = true)
public Address getAddress() {
return this.address;
}

}



@javax.persistence.Embeddable
public class Address implements Serializable {
private static final long serialVersionUID = -2023844913320728453L;

@Column(name = "city", length = 60)
private String city;

@Column(name = "postal_code", length = 10)
private String postalCode;

@Column(name = "street")
private String street;

@Column(name = "local", length = 10)
private String local;

public String getCityPart() {
StringBuffer bf = new StringBuffer();
if (this.postalCode != null) {
bf.append(this.postalCode);
bf.append(" ");
}
if (this.city != null) {
bf.append(this.city);
}
return bf.toString();
}

public String getStreetPart() {
StringBuffer bf = new StringBuffer();
if (this.street != null) {
bf.append(this.street);
}
if (this.local != null) {
bf.append(" ");
bf.append(this.local);
}
return bf.toString();
}

@DynamicDataProperty
public String getFull() {
StringBuffer bf = new StringBuffer();
bf.append(getStreetPart());
if (bf.length() > 0) {
bf.append(", ");
}
bf.append(getCityPart());
return bf.toString();
}

@DynamicDataProperty
public String getCity() {
return this.city;
}

public void setCity(String city) {
this.city = city;
}

@DynamicDataProperty
public String getPostalCode() {
return this.postalCode;
}

public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}

@DynamicDataProperty
public String getStreet() {
return this.street;
}

public void setStreet(String street) {
this.street = street;
}

@DynamicDataProperty
public String getLocal() {
return this.local;
}

public void setLocal(String local) {
this.local = local;
}

}



Jak widać wszystkie gettery zarówno w klasie Customer jak i Address zostały oznaczone adnotacją co powoduje, że wszystkie propery będą przekazywane pomiędzy częścią serwerową i kliencką aplikacji. Dodatkowo getAddress() został oznaczony adnotacją z ustawieniem embeded = true co oznacza, że property dotyczy obiektu zanurzonego, lub inaczej mówiąc obiektu którego serializacja i deserializacja powinna dotyczyć w sensie serializacji jego property.

Teraz tworzymy dwie klasy obiekty których będą przesyłane pomiędzy częścią serwerową i kliencką. Są to klasy do przesyłania zserializowanej postaci obiektów domenowych, czyli swojego rodzaju generyczne DTO. Tak więc mamy klasę konetenerową:

public class DynamicData extends AbstractData {
private static final long serialVersionUID = -2549646020563019965L;

private LinkedHashMap map = new LinkedHashMap();

public LinkedHashMap getMap() {
return this.map;
}

@Override
public Long getId() {
DataProperty prop = this.map.get("id");
return (Long) (prop != null ? prop.getValue() : null);
}
}


i klasę komponentową:

public class DataProperty implements Serializable {
private static final long serialVersionUID = -4627984997682982978L;

private DataPropertyType type = DataPropertyType.STRING;
private String str;
private Integer integer;
private Short shortv;
private Long longv;
private Boolean boolv;
private DynamicData embebed;

public DataProperty() {
this("");
}

public DataProperty(Object value) {
if (value == null) {
throw new IllegalArgumentException("Value cannot be null");
}
if (value instanceof String) {
this.str = (String) value;
} else if ((value instanceof DynamicData)) {
this.embebed = (DynamicData) value;
this.type = DataPropertyType.EMBEDED;
} else if ((value instanceof Boolean)) {
this.boolv = (Boolean) value;
this.type = DataPropertyType.BOOL;
} else if ((value instanceof Short)) {
this.shortv = ((Short) value);
this.type = DataPropertyType.SHORT;
} else if ((value instanceof Integer)) {
this.integer = (Integer) value;
this.type = DataPropertyType.INT;
} else if (value instanceof Long) {
this.longv = (Long) value;
this.type = DataPropertyType.LONG;
} else {
this.str = value.toString();
}
}

public Object getValue() {
switch (this.type) {
case EMBEDED:
return this.embebed;
case BOOL:
return this.boolv;
case SHORT:
return this.shortv;
case INT:
return this.integer;
case LONG:
return this.longv;
default:
return this.str;
}
}

public DataPropertyType getType() {
return this.type;
}
}


public enum DataPropertyType implements Serializable {

STRING,
INT,
LONG,
BOOL,
EMBEDED,
SHORT;
}



Jak widać w klasie komponentowej każdy typ ma swoje pole. Można by zapytać dlaczego nie zrobić jednego pola typu Object, w którym zapisana była by informacja o zserializowanej wartości. Rzeczywiście tak by było najprościej, ale niestety jest to problematyczne z racji wykorzystania GWT. Ponieważ obiekty komponentowe będą przesyłane na stronę kliencką muszą być skompilowane przez GWT do javasrcipt-u i jeżeli damy Obiect kompilator będzie próbował stworzyć generyczny javascript i tu dostaniemy albo warningi przy kompilacji albo problemy przy serializacji w runtime. Dlatego najlepiej jest wyręczyć kompilator GWT i samemu przygotować implementację opierająca się o jasno określone typy serializowanych wartości.

No dobrze mamy klasy domenowe, mamy komponenty umożliwiające nam przekazywanie informacji pomiędzy częścią serwerową i kliencką teraz potrzebujemy serializatorów. Serializator po stronie klienckiej ma następującą postać:

public class DynamicDataMapper {
private static final Logger log = LoggerFactory.getLogger(DynamicDataMapper.class);

private DynamicDataMapper() {
}

public static void map(DynamicData data, T entity) {
if ((data != null) && (entity != null)) {
try {
to(data, entity);
} catch (Exception e) {
throw new MappingException(e);
}
}
}

public static DynamicData map(T entity) {
DynamicData data = null;
if (entity != null) {
data = new DynamicData();
try {
from(data, entity);
} catch (Exception e) {
throw new MappingException(e);
}
}
return data;
}

private static void to(DynamicData data, Object inst) throws Exception {
PropertyDescriptor[] desc = ReflectUtils.getBeanProperties(inst.getClass());
Map propMap = new HashMap();
for (PropertyDescriptor d : desc) {
propMap.put(d.getName(), d);
}
LinkedHashMap map = data.getMap();
for (Entry entry : map.entrySet()) {
String key = entry.getKey();
try {
DataProperty prop = entry.getValue();
PropertyDescriptor d = propMap.get(key);
if (d != null) {
Object value = prop != null ? prop.getValue() : null;
//log.debug("PROP: {}, VALUE: {}", key, value);
if (value instanceof DynamicData) {
Method mth = d.getReadMethod();
if (mth != null) {
Object bean = mth.invoke(inst, new Object[0]);
if (bean != null) {
to((DynamicData) value, bean);
}
}
} else {
Method mth = d.getWriteMethod();
if (mth != null) {
//Class clas = mth.getParameterTypes()[0];
//log.debug("Parameter class: {}", clas);
mth.invoke(inst, value);
}
}
}
} catch (Exception ex) {
throw new MappingException("Error for Parameter " + key, ex);
}
}
}

private static void from(DynamicData data, Object inst) throws Exception {
PropertyDescriptor[] desc = ReflectUtils.getBeanProperties(inst.getClass());
for (PropertyDescriptor des : desc) {
Method mth = des.getReadMethod();
if (mth != null) {
DynamicDataProperty an = mth.getAnnotation(DynamicDataProperty.class);
if (an != null) {
String key = des.getName();
Object result = mth.invoke(inst, new Object[0]);
DataProperty prop = null;
if (result != null) {
if (an.embeded()) {
DynamicData embeded = new DynamicData();
from(embeded, result);
result = embeded;
}
prop = new DataProperty(result);
}
data.getMap().put(key, prop);
}
}
}
}

}


Serializator ma dwie metody statyczne from i to służące do serializacji i deserializacji przekazywanych komponentów. Serializacja polega na zapisaniu property z obiektu domenowego w postaci mapy property, gdzie kluczem jest nazwa a wartością obiekt komponentowy DataProperty zawierający wartość odczytaną z obiektu domenowego. W przypadku property typu embeded tworzony nowy obiekt DynamicData i zapisywany jako wartość w odpowiednim DataProperty.

No dobrze mamy część serwerową no to czas na część kliencką i oto i ona:

public class DynamicDataSource extends TableDataSource {

private static final Converter CONVERTER = new Converter();

public DynamicDataSource(DataServiceAsync service, SortSpecifier[] sort) {
super(service, sort);
}

public DynamicDataSource(DataServiceAsync service) {
super(service);
}

@Override
public IConverter getRecordConverter() {
return CONVERTER;
}

static class Converter implements IConverter {

@Override
public void convertData(Record rec, DynamicData element) {
this.convertData(rec, null, element);
}

@Override
public DynamicData convertRecord(Record rec) {
DynamicData data = new DynamicData();
String[] attrs = rec.getAttributes();
for (String attr : attrs) {
if (Log.isDebugEnabled()) {
Log.debug("Processing attribute: " + attr);
}
LinkedHashMap map = getMap(attr, data);
Object value = rec.getAttributeAsObject(attr);
int idx = attr.lastIndexOf('.');
if (idx > -1) {
attr = attr.substring(idx + 1);
}
DataProperty dp = null;
if (value != null) {
if (value instanceof JavaScriptObject) {
value = JSOHelper.convertToJava((JavaScriptObject) value);
}
if (Log.isDebugEnabled()) {
Log.debug("VALUE calss: " + value.getClass() + " - " + value);
}
dp = new DataProperty(value);
}
map.put(attr, dp);
}
return data;
}

private LinkedHashMap getMap(String attr, DynamicData data) {
LinkedHashMap map = data.getMap();
int idx = attr.indexOf('.');
if (idx > -1) {
String at = attr.substring(0, idx);
DataProperty dp = map.get(at);
if (dp == null) {
DynamicData md = new DynamicData();
dp = new DataProperty(md);
map.put(at, dp);
}
return getMap(attr.substring(idx + 1), (DynamicData) dp.getValue());
}
return map;
}

private void convertData(Record rec, String prop, DynamicData element) {
LinkedHashMap map = element.getMap();
for (Entry entry : map.entrySet()) {
Object value = null;
String property = prop != null ? prop + "." + entry.getKey() : entry.getKey();
DataProperty dp = entry.getValue();
if (dp != null) {
value = dp.getValue();
}
if (value instanceof DynamicData) {
convertData(rec, property, (DynamicData) value);
} else {
rec.setAttribute(property, value);
}
}
}

}
}


Część kliencka jest w postaci DataSource i mamy tutaj metodę convertData() która służy do konwersji obiektu generycznego DTO na atrybuty w rekordzie DataSource-a oraz metodę convertRecord(), która konwertuje dane z rekordu na odpowiedni obiekt generyczny DTO.

Lunux - karta TV: przydatne komendy

, środa, 9 marca 2011 0 komentarze

Pokaż załadowane moduły ograniczając się do cx

sudo lsmod | grep cx


cx8800 29418 0
cx88xx 74190 1 cx8800
rc_core 17007 7 ir_lirc_codec,ir_sony_decoder,ir_jvc_decoder,ir_rc6_decoder,ir_rc5_decoder,ir_nec_decoder,cx88xx
i2c_algo_bit 5205 1 cx88xx
tveeprom 13145 1 cx88xx
v4l2_common 8312 3 tuner,cx8800,cx88xx
videodev 69118 4 tuner,cx8800,cx88xx,v4l2_common
videobuf_dma_sg 8668 2 cx8800,cx88xx
videobuf_core 16044 3 cx8800,cx88xx,videobuf_dma_sg
btcx_risc 3738 2 cx8800,cx88xx
i2c_core 27089 11 tuner_simple,tea5767,nvidia,tuner,cx8800,cx88xx,i2c_algo_bit,tveeprom,v4l2_common,videodev,i2c_i801


Wyświetl bufor warstwy jądra ograniczając się do wpisów zawierających cx
dmesg | grep cx


[ 11.199826] cx88/0: cx2388x v4l2 driver version 0.0.8 loaded
[ 11.199872] cx8800 0000:05:02.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
[ 11.202933] cx88[0]: subsystem: 0000:0000, board: PixelView [card=3,insmod option], frontend(s): 0
[ 11.202937] cx88[0]: TV tuner type 23, Radio tuner type 23
[ 11.202939] cx88[0]: cx88_reset
[ 11.314193] cx88[0]: Test OK
[ 11.392886] cx88[0]: i2c scan: found device @ 0xc0 [tuner (analog)]
[ 12.606248] tuner 1-0060: chip found @ 0xc0 (cx88[0])
[ 12.641231] cx88[0]/0: found at 0000:05:02.0, rev: 3, irq: 18, latency: 32, mmio: 0xf9000000
[ 12.641671] cx88[0]/0: registered device video0 [v4l2]
[ 12.641883] cx88[0]/0: registered device vbi0
[ 12.642005] cx88[0]/0: registered device radio0
[ 12.642052] cx88[0]: set_tvnorm: "NTSC-M" fsc8=28636360 adc=28636363 vdec=28636360 db/dr=28636360/28636360
[ 12.642058] cx88[0]: set_pll: MO_PLL_REG 0x00fffffe [old=0x00f15f18,freq=28636360]
[ 12.642063] cx88[0]: pll locked [pre=2,ofreq=28636360]
[ 12.642067] cx88[0]: set_tvnorm: MO_INPUT_FORMAT 0x00000001 [old=0x00000007]
[ 12.642073] cx88[0]: set_tvnorm: MO_OUTPUT_FORMAT 0x181f0008 [old=0x181f0000]
[ 12.642078] cx88[0]: set_tvnorm: MO_SCONV_REG 0x00020000 [old=0x00021f07]
[ 12.642082] cx88[0]: set_tvnorm: MO_SUB_STEP 0x00400000 [old=0x0043e0f8]
[ 12.642087] cx88[0]: set_tvnorm: MO_SUB_STEP_DR 0x00400000 [old=0x00538e38]
[ 12.642092] cx88[0]: set_tvnorm: MO_AGC_BURST 0x00007270 [old=0x00006d63,bdelay=114,agcdelay=112]
[ 12.642097] cx88[0]: set_tvnorm: MO_HTOTAL 0x0000038e [old=0x0000135a,htotal=910]
[ 12.642100] cx88[0]: set_scale: 320x240 [TB,NTSC-M]
[ 12.642103] cx88[0]: set_scale: hdelay 0x0038 (width 754)
[ 12.642105] cx88[0]: set_scale: hscale 0x15b3
[ 12.642107] cx88[0]: set_scale: hactive 0x0140
[ 12.642109] cx88[0]: set_scale: vdelay 0x0018
[ 12.642111] cx88[0]: set_scale: vscale 0x1e00
[ 12.642113] cx88[0]: set_scale: vactive 0x01e0
[ 12.642115] cx88[0]: set_scale: filter 0x80009
[ 12.642121] cx88[0]/0: set_audio_standard_BTSC (status: known-good)
[ 12.643011] cx88[0]/0: set_control id=0x980900(Brightness) ctrl=0x7f, reg=0x310110 val=0xff (mask 0xff)
[ 12.643056] cx88[0]/0: set_control id=0x980901(Contrast) ctrl=0x3f, reg=0x310110 val=0x3f00 (mask 0xff00)
[ 12.643063] cx88[0]/0: set_control id=0x980903(Hue) ctrl=0x7f, reg=0x310118 val=0xff (mask 0xff)
[ 12.643069] cx88[0]/0: set_control id=0x980902(Saturation) ctrl=0x7f, reg=0x310114 val=0x5a7f (mask 0xffff)
[ 12.643074] cx88[0]/0: set_control id=0x98091D(Chroma AGC) ctrl=0x01, reg=0x310104 val=0x400 (mask 0x400)
[ 12.643079] cx88[0]/0: set_control id=0x98091E(Color killer) ctrl=0x01, reg=0x310104 val=0x200 (mask 0x200)
[ 12.643084] cx88[0]/0: set_control id=0x980909(Mute) ctrl=0x01, reg=0x320594 val=0x40 (mask 0x40) [shadowed]
[ 12.643088] cx88[0]/0: set_control id=0x980905(Volume) ctrl=0x3f, reg=0x320594 val=0x00 (mask 0x3f) [shadowed]
[ 12.643092] cx88[0]/0: set_control id=0x980906(Balance) ctrl=0x40, reg=0x320598 val=0x00 (mask 0x7f) [shadowed]
[ 12.643096] cx88[0]/0: video_mux: 0 [vmux=0,gpio=0xff00,0x0,0x0,0x0]
[ 12.647184] cx88[0]/0: cx88: tvaudio thread started
[ 12.664972] cx88[0]/0: open dev=vbi0 radio=0 type=vbi-cap
[ 12.665165] cx88[0]/0: open dev=radio0 radio=1 type=(null)
[ 12.665169] cx88[0]/0: video_open: setting radio device
[ 12.665173] cx88[0]/0: set_audio_standard_FM (status: unknown)
[ 12.665197] cx88[0]/0: cx88_set_stereo: mask 0x3f, ctl 0x1a [status=0x22,ctl=0x101a,vol=0x40]
[ 12.666213] cx88[0]/0: open dev=video0 radio=0 type=vid-cap
[ 27.217735] cx88[0]/0: open dev=radio0 radio=1 type=(null)
[ 27.217742] cx88[0]/0: video_open: setting radio device
[ 27.217745] cx88[0]/0: set_audio_standard_FM (status: unknown)
[ 27.217769] cx88[0]/0: cx88_set_stereo: mask 0x3f, ctl 0x1a [status=0x22,ctl=0x101a,vol=0x40]
[ 27.220711] cx88[0]/0: open dev=vbi0 radio=0 type=vbi-cap
[ 27.222937] cx88[0]/0: open dev=video0 radio=0 type=vid-cap
[ 239.487766] cx88[0]/0: open dev=video0 radio=0 type=vid-cap


Wyświetl karty dźwiękowe
cat /proc/asound/cards


0 [Intel ]: HDA-Intel - HDA Intel
HDA Intel at 0xfb000000 irq 45
1 [Audigy ]: Audigy - SB Audigy 1 [SB0092]
SB Audigy 1 [SB0092] (rev.3, serial:0x531102) at 0xd000, irq 20


Wyświetl listę urządzeń typu audio
aplay -l


**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC888 Analog [ALC888 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: ALC888 Digital [ALC888 Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Audigy [SB Audigy 1 [SB0092]], device 0: emu10k1 [ADC Capture/Standard PCM Playback]
Subdevices: 32/32
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
Subdevice #8: subdevice #8
Subdevice #9: subdevice #9
Subdevice #10: subdevice #10
Subdevice #11: subdevice #11
Subdevice #12: subdevice #12
Subdevice #13: subdevice #13
Subdevice #14: subdevice #14
Subdevice #15: subdevice #15
Subdevice #16: subdevice #16
Subdevice #17: subdevice #17
Subdevice #18: subdevice #18
Subdevice #19: subdevice #19
Subdevice #20: subdevice #20
Subdevice #21: subdevice #21
Subdevice #22: subdevice #22
Subdevice #23: subdevice #23
Subdevice #24: subdevice #24
Subdevice #25: subdevice #25
Subdevice #26: subdevice #26
Subdevice #27: subdevice #27
Subdevice #28: subdevice #28
Subdevice #29: subdevice #29
Subdevice #30: subdevice #30
Subdevice #31: subdevice #31
card 1: Audigy [SB Audigy 1 [SB0092]], device 2: emu10k1 efx [Multichannel Capture/PT Playback]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: Audigy [SB Audigy 1 [SB0092]], device 3: emu10k1 [Multichannel Playback]
Subdevices: 1/1
Subdevice #0: subdevice #0


Wyświetl urządzenia PCI ze szczegółami
lspci -vvv


05:00.2 FireWire (IEEE 1394): Creative Labs SB Audigy FireWire Port (prog-if 10 [OHCI])
Subsystem: Creative Labs SB Audigy FireWire Port
Flags: bus master, medium devsel, latency 32, IRQ 19
Memory at fa005000 (32-bit, non-prefetchable) [size=2K]
Memory at fa000000 (32-bit, non-prefetchable) [size=16K]
Capabilities: [44] Power Management version 2
Kernel driver in use: firewire_ohci
Kernel modules: firewire-ohci

05:01.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)
Subsystem: Edimax Computer Co. Device 9503
Flags: bus master, medium devsel, latency 64, IRQ 19
I/O ports at d200 [size=256]
Memory at fa004000 (32-bit, non-prefetchable) [size=256]
Capabilities: [50] Power Management version 2
Kernel driver in use: 8139too
Kernel modules: 8139too, 8139cp

05:02.0 Multimedia video controller: Conexant Systems, Inc. CX23880/1/2/3 PCI Video and Audio Decoder (rev 03)
Flags: bus master, medium devsel, latency 32, IRQ 18
Memory at f9000000 (32-bit, non-prefetchable) [size=16M]
Capabilities: [44] Vital Product Data
Capabilities: [4c] Power Management version 2
Kernel driver in use: cx8800
Kernel modules: cx8800

GlossyBlue Blogger by Black Quanta. Theme & Icons by N.Design Studio
Entries RSS Comments RSS