Wicket のAJAX でアドレスのマスク計算チェックを作ってみた。
長いので2回に分けて投稿
まずは、Panel 化したJava ソース
import java.math.BigInteger;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.behavior.HeaderContributor;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.CSSPackageResource;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.validation.validator.RangeValidator;
/**
* Ipv4 mask calculate Panel
*/
public class IpmaskCalcPanel extends Panel{
String sg1binstr;
String sg1hexstr;
************************
省略! 2,3,4 も同様
************************
String resultstr;
public IpmaskCalcPanel(String id){
super(id);
final FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
add(feedback);
Form<Void> form = new Form<Void>("ipmaskcalcform");
form.add(getCSS());
final TextField<Integer> sg1
= new RequiredTextField<Integer>("sg1",new Model<Integer>());
sg1.setType(Integer.class);
sg1.add(new RangeValidator<Integer>(0,255));
************************
省略! 2,3,4 も同様
************************
final TextField<Integer> mask
= new RequiredTextField<Integer>("mask",new Model<Integer>());
mask.setType(Integer.class);
mask.add(new RangeValidator<Integer>(1,32));
//
final Label sg1bin = new Label("sg1bin",new PropertyModel(this,"sg1binstr"));
sg1bin.setOutputMarkupId(true);
final Label sg1hex = new Label("sg1hex",new PropertyModel(this,"sg1hexstr"));
sg1hex.setOutputMarkupId(true);
************************
省略! 2,3,4 も同様
************************
sg1.add(new OnChangeAjaxBehavior(){
@Override
protected void onUpdate(AjaxRequestTarget target){
Integer i = sg1.getConvertedInput();
IpmaskCalcPanel.this.sg1binstr = i==null ? null : displayBinary(i);
IpmaskCalcPanel.this.sg1hexstr = i==null ? null : String.format("%02X",i);
target.addComponent(sg1bin);
target.addComponent(sg1hex);
}
});
************************
省略! 2,3,4 も同様
************************
final TextField<Integer> ip1
= new RequiredTextField<Integer>("ip1",new Model<Integer>());
ip1.setType(Integer.class);
ip1.add(new RangeValidator<Integer>(0,255));
************************
省略! 2,3,4 も同様
************************
//
final Label ip1bin = new Label("ip1bin",new PropertyModel(this,"ip1binstr"));
ip1bin.setOutputMarkupId(true);
final Label ip1hex = new Label("ip1hex",new PropertyModel(this,"ip1hexstr"));
ip1hex.setOutputMarkupId(true);
************************
省略! 2,3,4 も同様
************************
ip1.add(new OnChangeAjaxBehavior(){
@Override
protected void onUpdate(AjaxRequestTarget target){
Integer i = ip1.getConvertedInput();
IpmaskCalcPanel.this.ip1binstr = i==null ? null : displayBinary(i);
IpmaskCalcPanel.this.ip1hexstr = i==null ? null : String.format("%02X",i);
target.addComponent(ip1bin);
target.addComponent(ip1hex);
}
});
************************
省略! 2,3,4 も同様
************************
final Label result = new Label("result",new PropertyModel(this,"resultstr"));
result.add(new SimpleAttributeModifier("class","reset"));
result.setOutputMarkupId(true);
form.add(new AjaxButton("submit"){
@Override
protected void onSubmit(AjaxRequestTarget target,Form<?> f){
Session.get().cleanupFeedbackMessages();
target.addComponent(feedback);
String segmentIP
= sg1.getModelObject().toString()+"."+sg2.getModelObject().toString()
+"."+sg3.getModelObject().toString()+"."+sg4.getModelObject();
String targetIP
= ip1.getModelObject().toString()+"."+ip2.getModelObject().toString()
+"."+ip3.getModelObject().toString()+"."+ip4.getModelObject();
if (isScorp(targetIP,segmentIP,mask.getModelObject())){
IpmaskCalcPanel.this.resultstr = "accepted";
result.add(new SimpleAttributeModifier("class","ok"));
}else{
IpmaskCalcPanel.this.resultstr = "reject";
result.add(new SimpleAttributeModifier("class","ng"));
}
target.addComponent(result);
}
@Override
protected void onError(final AjaxRequestTarget target, final Form ff){
IpmaskCalcPanel.this.resultstr =null;
result.add(new SimpleAttributeModifier("class","reset"));
target.addComponent(result);
target.addComponent(feedback);
}
});
form.add(sg1bin);
form.add(sg1hex);
************************
省略! 2,3,4 も同様
************************
form.add(ip1bin);
form.add(ip1hex);
************************
省略! 2,3,4 も同様
************************
form.add(ip1);
************************
省略! 2,3,4 も同様
************************
form.add(sg1);
************************
省略! 2,3,4 も同様
************************
form.add(mask);
form.add(result);
add(form);
}
protected String displayBinary(Integer i){
String s = String.format("%8s"
,Integer.toBinaryString(i)).replaceAll(" ","0");
return s.substring(0,4)+" "+s.substring(4);
}
// CSS
protected HeaderContributor getCSS(){
return CSSPackageResource
.getHeaderContribution(IpmaskCalcPanel.class,"IpmaskCalc.css");
}
/**
* サブネットマスク検査.
*/
protected boolean isScorp(String ipaddr,String segaddr,int len){
byte bmask = this.getMask(len);
byte bseg = this.addrTobyte(segaddr);
BigInteger minBigInt = new BigInteger(this.byteAND(bseg,bmask));
byte bmax
= this.byteOR(bseg,this.byteXOR(bmask,addrTobyte("255.255.255.255")));
BigInteger maxBigInt = new BigInteger(bmax);
BigInteger bchk = new BigInteger(addrTobyte(ipaddr));
return
minBigInt.compareTo(bchk) <= 0
&& bchk.compareTo(maxBigInt) <= 0 ? true : false;
}
private byte getMask(int n){
byte b = new BigInteger(1,new byte{-1,-1,-1,-1})
.shiftRight(n)
.xor(new BigInteger(1,new byte{-1,-1,-1,-1}))
.toByteArray();
byte br = new byte[4];
for(int i=0;i < br.length;i++){
br[i] = b[i+1];
}
return br;
}
private byte addrTobyte(String s){
String sp = s.split("\\.");
byte b = new byte[4];
for(int i=0;i < 4;i++){
b[i] = (byte)(Integer.parseInt(sp[i]));
}
return b;
}
private byte byteAND(byte b1,byte b2){
byte r = new byte[b1.length];
for(int i=0;i < r.length;i++){
r[i] = (byte)(b1[i] & b2[i]);
}
return r;
}
private byte byteOR(byte b1,byte b2){
byte r = new byte[b1.length];
for(int i=0;i < r.length;i++){
r[i] = (byte)(b1[i] | b2[i]);
}
return r;
}
private byte byteXOR(byte b1,byte b2){
byte[] r = new byte[b1.length];
for(int i=0;i < r.length;i++){
r[i] = (byte)(b1[i] ^ b2[i]);
}
return r;
}
}