1 20 21 package org.netbeans.modules.j2ee.websphere6.config.sync; 22 23 import java.io.*; 24 import java.util.*; 25 import javax.xml.parsers.*; 26 import javax.xml.xpath.*; 27 import org.netbeans.api.project.FileOwnerQuery; 28 import org.netbeans.api.project.Project; 29 import org.netbeans.api.project.ui.OpenProjects; 30 import org.netbeans.modules.j2ee.spi.ejbjar.EjbJarProvider; 31 import org.netbeans.modules.j2ee.websphere6.dd.beans.DDXmiConstants; 32 import org.netbeans.spi.project.SubprojectProvider; 33 import org.openide.filesystems.FileUtil; 34 import org.w3c.dom.*; 35 import org.xml.sax.SAXException ; 36 import static org.netbeans.modules.j2ee.websphere6.config.WarDeploymentConfiguration.WEB_APP_ID; 37 38 42 public class WarSynchronizer extends Synchronizer{ 43 private File ibmwebbndFile; 44 private File webxmlFile; 45 private XPath xpath = null; 46 private boolean saveIbmWebBndNeeded = false; 47 private boolean saveWebXmlNeeded = false; 48 49 50 53 public WarSynchronizer(File webxmlFilePar, File ibmwebbndFilePar) { 54 this.webxmlFile = webxmlFilePar; 55 this.ibmwebbndFile = ibmwebbndFilePar; 56 try { 57 xpath = XPathFactory.newInstance(XPathConstants.DOM_OBJECT_MODEL).newXPath(); 58 } catch (Exception ex) { 59 ex.printStackTrace(); 60 xpath = null; 61 } 62 } 63 64 65 public synchronized void syncDescriptors() { 66 if ((webxmlFile != null) && (ibmwebbndFile != null)) { 67 try { 68 saveIbmWebBndNeeded = false; 69 saveWebXmlNeeded = false; 70 71 72 Document webDocument = loadDocument(webxmlFile); 73 Document ibmwebbndDocument = loadDocument(ibmwebbndFile); 74 75 syncEjbReferences(webDocument,ibmwebbndDocument); 76 77 syncRootId(webDocument,ibmwebbndDocument); 78 79 if (saveWebXmlNeeded) { 80 saveDocument(webDocument, webxmlFile); 81 } 82 if (saveIbmWebBndNeeded) { 83 84 saveDocument(ibmwebbndDocument, ibmwebbndFile); 85 } 86 } catch (Exception ex) { 87 ex.printStackTrace(); 88 } 89 } 90 } 91 private void syncRootId(Document webDocument,Document ibmwebbndDocument) { 92 if (!WEB_APP_ID.equals(webDocument.getDocumentElement().getAttribute("id"))) { 93 Attr attribute = webDocument.createAttribute("id"); 94 attribute.setValue(WEB_APP_ID); 95 webDocument.getDocumentElement().getAttributes().setNamedItem(attribute); 96 saveWebXmlNeeded = true; 97 } 98 } 99 100 private enum Reference { 101 LOCAL, REMOTE; 102 public String getTagName() { 103 switch(this) { 104 case LOCAL: return "ejb-local-ref"; 105 case REMOTE: return "ejb-ref"; 106 } 107 return null; 108 } 109 public boolean isLocal() { 110 switch(this) { 111 case LOCAL: return true; 112 case REMOTE: return false; 113 } 114 return false; 115 } 116 public boolean isRemote() { 117 switch(this) { 118 case LOCAL: return false; 119 case REMOTE: return true; 120 } 121 return false; 122 } 123 }; 124 125 private void syncEjbReferences(Document webDocument,Document ibmwebbndDocument) { 126 try { 127 128 129 String [] tags = new String [] {"ejb-ref", "ejb-local-ref"}; 130 for(Reference reference : new Reference[] {Reference.LOCAL, Reference.REMOTE}) { 131 NodeList enterpriseBeansList = (NodeList) xpath. 132 compile("./" + reference.getTagName()). 133 evaluate(webDocument.getDocumentElement(), XPathConstants.NODESET); 134 135 136 Node bindingsRoot = ibmwebbndDocument.getDocumentElement(); 137 if (bindingsRoot == null) { 138 return; 139 } 140 141 NodeList ejbBindingsList = (NodeList) xpath. 142 compile("./"+ DDXmiConstants.EJB_REF_BINDINGS_ID). 143 evaluate(bindingsRoot, XPathConstants.NODESET); 144 145 146 for (int i = 0; i < enterpriseBeansList.getLength(); i++) { 147 Node node = enterpriseBeansList.item(i); 148 149 String id = getBeanId(node); 150 if ((id == null) || (!bindingExists(bindingsRoot, id))) { 151 String interfaceName = getInterfaceName(node,reference); 152 String refName = getEjbRefNameName(node); 153 if (id == null) { 154 id = createBeanId(node, refName); 155 } 156 157 Attr attribute = webDocument.createAttribute("id"); 158 attribute.setValue(id); 159 160 node.getAttributes().setNamedItem(attribute); 161 162 Node binding = constructBinding(ibmwebbndDocument, 163 getBeanId(node), 164 getBindingJNDIName(interfaceName,reference),reference); 165 bindingsRoot.appendChild(ibmwebbndDocument.createTextNode(" ")); 166 bindingsRoot.appendChild(binding); 167 bindingsRoot.appendChild(ibmwebbndDocument.createTextNode("\n")); 168 saveIbmWebBndNeeded = true; 169 saveWebXmlNeeded = true; 170 } 171 } 172 173 for (int i = 0; i < ejbBindingsList.getLength(); i++) { 174 Node node = ejbBindingsList.item(i); 175 176 String id = getBindingId(node); 177 178 String type = getBindingType(node); 179 180 if(((DDXmiConstants.BINDING_EJB_REF_TYPE_LOCAL_STRING).equals(type) && 181 reference.isLocal()) || 182 (type==null && reference.isRemote()) ) { 183 if (!ejbReferenceExists(webDocument, id, reference) || 184 !isEjbReferenceValid(webDocument,id,reference)) { 185 bindingsRoot.removeChild(node); 186 saveIbmWebBndNeeded = true; 187 } 188 } 189 } 190 } 191 192 } catch (Exception e) { 193 e.printStackTrace(); 194 } 195 } 196 197 private String getReferenceJNDIName(Object [] dirList,String interfaceName,Reference reference) { 198 if(dirList == null || dirList.length == 0) { 199 return null; 200 } 201 for(int i=0;i<dirList.length;i++) { 202 File dir = (File) dirList [i]; 203 File ejbJarFile = new File(dir, "src" + File.separator+ "conf" + File.separator + "ejb-jar.xml"); 204 File ejbJarBndFile = new File(dir, "src" + File.separator+"conf"+File.separator+"ibm-ejb-jar-bnd.xmi"); 205 206 String jndiName = null; 207 BufferedReader reader = null; 208 try { 209 210 Document ejbJarDocument = loadDocument(ejbJarFile); 211 Document ibmEjbJarBndDocument = loadDocument(ejbJarBndFile); 212 Node session = (Node) xpath. 213 compile("./enterprise-beans/session[" + 214 (reference.isLocal() ? 215 "local" : "remote" ) + "=\"" + 216 interfaceName + "\"]"). 217 evaluate(ejbJarDocument.getDocumentElement(), XPathConstants.NODE); 218 Node sessionIdNode = session.getAttributes().getNamedItem("id"); 219 String sessionId = sessionIdNode.getTextContent(); 220 221 Node hrefNode = (Node) xpath. 222 compile("./ejbBindings/enterpriseBean[@href=\"META-INF/ejb-jar.xml#" + sessionId + "\"]"). 223 evaluate(ibmEjbJarBndDocument.getDocumentElement(), XPathConstants.NODE); 224 225 jndiName = hrefNode.getParentNode().getAttributes().getNamedItem(DDXmiConstants.JNDI_NAME_ID).getTextContent(); 226 227 addSyncFile(ejbJarFile); 228 229 } catch (NullPointerException e) { 230 continue; 232 } catch (XPathExpressionException e) { 233 continue; 235 } finally { 236 if(reader!=null) { 237 try { 238 reader.close(); 239 } catch(IOException ex) { 240 ex=null; 241 } 242 } 243 } 244 return jndiName; 245 } 246 return null; 247 } 248 249 private String getInterfaceName(Node beanNode, Reference reference) throws XPathExpressionException { 250 String intName = ((Node) xpath.compile( 251 reference.isLocal() ? "child::local" : "child::remote"). 252 evaluate(beanNode, XPathConstants.NODE)). 253 getTextContent(); 254 return intName; 255 } 256 private String getEjbRefNameName(Node beanNode) throws XPathExpressionException { 257 String refName = ((Node) xpath.compile( 258 "child::ejb-ref-name"). 259 evaluate(beanNode, XPathConstants.NODE)). 260 getTextContent(); 261 return refName; 262 } 263 264 private String getBeanId(Node beanNode) { 265 Node idNode = beanNode.getAttributes().getNamedItem("id"); 266 267 return (idNode != null)? idNode.getTextContent() : null; 268 } 269 private Object [] getEjbDirectoryList() { 270 ArrayList <File> list = new ArrayList <File> (); 271 Project currentProject = FileOwnerQuery.getOwner(FileUtil.toFileObject(webxmlFile)); 272 File webProjectFolder = FileUtil.toFile(currentProject.getProjectDirectory()); 273 Properties props = new Properties(); 274 Document projectXml = loadDocument(new File(webProjectFolder, "nbproject" + File.separator + "project.xml")); 275 try { 276 NodeList refProjectNames = (NodeList) xpath.compile("./configuration/references/reference/foreign-project"). 277 evaluate(projectXml.getDocumentElement(), XPathConstants.NODESET); 278 for(int i=0;i<refProjectNames.getLength();i++) { 279 String name = refProjectNames.item(i).getTextContent(); 280 try { 281 InputStream is = new FileInputStream(new File(webProjectFolder, "nbproject" + File.separator + "project.properties")); 282 props.clear(); 283 props.load(is); 284 is.close(); 285 String dir = props.getProperty("project." + name); 286 if(dir!=null) { 287 list.add(new File(webProjectFolder, dir)); 288 } 289 } catch (IOException ex) { 290 ex.printStackTrace(); 291 } 292 } 293 } catch (XPathExpressionException ex) { 294 ex.printStackTrace(); 295 } 296 return list.toArray(); 297 } 298 299 private String getBindingJNDIName(String interfaceName,Reference referece) throws XPathFactoryConfigurationException, XPathExpressionException { 300 return getReferenceJNDIName(getEjbDirectoryList(),interfaceName, referece); 301 } 302 303 private String createBeanId(Node beanNode, String refName) throws XPathFactoryConfigurationException, XPathExpressionException { 304 String name = refName; 305 if(name.lastIndexOf("/")!=-1) { 306 name = name.substring(name.lastIndexOf("/")+1); 307 } 308 name = name.replaceAll("\\.","_"); 309 return name + BINDING_SEPARATOR + new Date().getTime(); 310 } 311 312 private boolean ejbReferenceExists(Document document, String id, Reference reference) throws XPathExpressionException, XPathFactoryConfigurationException { 313 314 String path = "./" + reference.getTagName() + "[@id=\"" + id + "\"]"; 315 316 Node node = (Node) xpath.compile(path).evaluate(document.getDocumentElement(), XPathConstants.NODE); 317 return node != null; 318 } 319 private boolean isEjbReferenceValid(Document document, String id, Reference reference) throws XPathExpressionException, XPathFactoryConfigurationException { 320 String path = "./" + reference.getTagName() + "[@id=\"" + id + "\"]"; 321 Node ejbRefNode = (Node) xpath.compile(path).evaluate(document.getDocumentElement(), XPathConstants.NODE); 322 323 String intName = ((Node) xpath.compile( 324 reference.isLocal() ? "child::local" : "child::remote"). 325 evaluate(ejbRefNode, XPathConstants.NODE)). 326 getTextContent(); 327 328 boolean result = (getReferenceJNDIName(getEjbDirectoryList(),intName,reference)!=null); 329 return result; 330 } 331 private String getBindingId(Node bindingNode) { 332 Node idNode = bindingNode.getAttributes().getNamedItem("xmi:id"); 333 334 if (idNode != null) { 335 return idNode.getTextContent(); 336 } else { 337 return null; 338 } 339 } 340 341 private String getBindingType(Node bindingNode) throws XPathExpressionException, XPathFactoryConfigurationException { 342 Node bind = (Node) xpath.compile("./bindingEjbRef").evaluate(bindingNode, XPathConstants.NODE); 343 Node typeNode = bind.getAttributes().getNamedItem("xmi:type"); 344 345 if (typeNode != null) { 346 return typeNode.getTextContent(); 347 } else { 348 return null; 349 } 350 } 351 352 private boolean bindingExists(Node root, String id) throws XPathFactoryConfigurationException, XPathExpressionException { 353 String path = "./" + DDXmiConstants.EJB_REF_BINDINGS_ID + "[@id=\"" + id + "\"]"; 354 355 Node node = (Node) xpath.compile(path).evaluate(root, XPathConstants.NODE); 356 357 return node != null; 358 } 359 360 private Node constructBinding(Document document, String id, String jndiName,Reference reference) { 361 Element binding = document.createElement(DDXmiConstants.EJB_REF_BINDINGS_ID); 362 binding.setAttribute(DDXmiConstants.JNDI_NAME_ID, (jndiName == null) ? "ejb/"+id : jndiName); 363 binding.setAttributeNS("http://www.omg.org/XMI", "xmi:id", id); 364 365 Element bean = document.createElement(DDXmiConstants.BINDING_EJB_REF_ID); 366 367 bean.setAttribute("href", "WEB-INF/web.xml#" + id); 368 if(reference.isLocal()) { 369 bean.setAttribute("xmi:type", DDXmiConstants.BINDING_EJB_REF_TYPE_LOCAL_STRING); 370 } 371 372 binding.appendChild(document.createTextNode("\n ")); 373 binding.appendChild(bean); 374 binding.appendChild(document.createTextNode("\n")); 375 return binding; 376 } 377 378 379 } 380 | Popular Tags |