001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 2004-2005 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.jmx.managerwizard;
042:
043: import com.sun.source.tree.AnnotationTree;
044: import com.sun.source.tree.AssignmentTree;
045: import com.sun.source.tree.BinaryTree;
046: import com.sun.source.tree.BlockTree;
047: import com.sun.source.tree.ClassTree;
048: import com.sun.source.tree.CompilationUnitTree;
049: import com.sun.source.tree.ExpressionStatementTree;
050: import com.sun.source.tree.ExpressionTree;
051: import com.sun.source.tree.IdentifierTree;
052: import com.sun.source.tree.LiteralTree;
053: import com.sun.source.tree.MemberSelectTree;
054: import com.sun.source.tree.MethodInvocationTree;
055: import com.sun.source.tree.MethodTree;
056: import com.sun.source.tree.NewArrayTree;
057: import com.sun.source.tree.NewClassTree;
058: import com.sun.source.tree.StatementTree;
059: import com.sun.source.tree.Tree;
060: import com.sun.source.tree.VariableTree;
061: import com.sun.source.util.TreePath;
062: import com.sun.source.util.TreePathScanner;
063: import java.util.List;
064: import java.text.MessageFormat;
065: import java.util.ArrayList;
066: import java.util.Collections;
067: import java.util.Set;
068: import java.util.HashSet;
069: import javax.lang.model.element.ExecutableElement;
070: import javax.lang.model.element.Modifier;
071: import javax.lang.model.element.TypeElement;
072: import org.netbeans.api.java.source.CancellableTask;
073: import org.netbeans.api.java.source.Comment;
074: import org.netbeans.api.java.source.JavaSource;
075: import org.netbeans.api.java.source.WorkingCopy;
076: import org.netbeans.api.java.source.TreeMaker;
077: import org.netbeans.modules.jmx.JavaModelHelper;
078: import org.openide.WizardDescriptor;
079: import org.openide.filesystems.FileObject;
080: import org.openide.loaders.DataObject;
081: import org.openide.loaders.DataFolder;
082: import org.netbeans.spi.project.ui.templates.support.Templates;
083: import org.netbeans.modules.jmx.WizardConstants;
084: import org.netbeans.modules.jmx.WizardHelpers;
085:
086: /**
087: *
088: * Wizard Agent code generator class
089: */
090: public class ManagerGenerator {
091: /**
092: * Entry point to generate manager code.
093: * @param wiz <CODE>WizardDescriptor</CODE> a wizard
094: * @throws java.io.IOException <CODE>IOException</CODE>
095: * @throws java.lang.Exception <CODE>Exception</CODE>
096: * @return <CODE>CreationResults</CODE> results of manager creation
097: */
098: public Set generateManager(final WizardDescriptor wiz)
099: throws java.io.IOException, Exception {
100: FileObject createdFile = null;
101: final String managerName = Templates.getTargetName(wiz);
102: FileObject managerFolder = Templates.getTargetFolder(wiz);
103: DataFolder managerFolderDataObj = DataFolder
104: .findFolder(managerFolder);
105:
106: //==============================================
107: // manager generation
108: //==============================================
109: DataObject managerDObj = null;
110:
111: FileObject template = Templates.getTemplate(wiz);
112: DataObject dTemplate = DataObject.find(template);
113: managerDObj = dTemplate.createFromTemplate(
114: managerFolderDataObj, managerName);
115: //Obtain an JavaSource - represents a java file
116: JavaSource js = JavaSource.forFileObject(managerDObj
117: .getPrimaryFile());
118: Boolean mainMethodSelected = (Boolean) wiz
119: .getProperty(WizardConstants.PROP_MANAGER_MAIN_METHOD_SELECTED);
120: //Perform an action which changes the content of the java file
121: js.runModificationTask(new CancellableTask<WorkingCopy>() {
122: public void run(WorkingCopy w) throws Exception {
123: //get information of the wizard descriptor
124: Boolean sampleSelected = (Boolean) wiz
125: .getProperty(WizardConstants.PROP_MANAGER_SAMPLE_CODE_SELECTED);
126: Boolean isSecurityChecked = (Boolean) wiz
127: .getProperty(WizardConstants.PROP_MANAGER_SECURITY_SELECTED);
128: Boolean isUserCredential = (Boolean) wiz
129: .getProperty(WizardConstants.PROP_MANAGER_USER_CREDENTIAL_SELECTED);
130: Boolean isSampleCredential = (Boolean) wiz
131: .getProperty(WizardConstants.PROP_MANAGER_CREDENTIAL_SAMPLE_SELECTED);
132: String userName = (String) wiz
133: .getProperty(WizardConstants.PROP_MANAGER_USER_NAME);
134: String userPassword = (String) wiz
135: .getProperty(WizardConstants.PROP_MANAGER_USER_PASSWORD);
136: String url = (String) wiz
137: .getProperty(WizardConstants.PROP_MANAGER_AGENT_URL);
138: w.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
139: //Visitor for scanning javac's trees
140: TemplateTransformer transformer = new TemplateTransformer(
141: w, managerName, sampleSelected == null ? false
142: : sampleSelected,
143: isSecurityChecked == null ? false
144: : isSecurityChecked,
145: isSampleCredential == null ? false
146: : isSampleCredential, userName,
147: userPassword, url,
148: isUserCredential == null ? false
149: : isUserCredential);
150: //execute the visitor on the root (CompilationUnitTree) with no parameter (null)
151: transformer.scan(new TreePath(w.getCompilationUnit()),
152: null);
153: }
154:
155: public void cancel() {
156: //Not important for userActionTasks
157: }
158: }).commit(); //Commit the changes into document
159:
160: if (!mainMethodSelected)
161: JavaModelHelper.removeMethod(js, "main");// NOI18N
162:
163: WizardHelpers.save(managerDObj);
164: Set set = new HashSet();
165: set.add(managerDObj.getPrimaryFile());
166: return set;
167: }
168:
169: private static class TemplateTransformer extends
170: TreePathScanner<Void, Object> {
171:
172: private final String className;
173: private final WorkingCopy w;
174: private final boolean sampleSelected;
175: private final boolean isSecurityChecked;
176: private final boolean isSampleCredential;
177: private final String userName;
178: private final String userPassword;
179: private final String url;
180: private final boolean isUserCredential;
181:
182: public TemplateTransformer(WorkingCopy w, String className,
183: boolean sampleSelected, boolean isSecurityChecked,
184: boolean isSampleCredential, String userName,
185: String userPassword, String url,
186: boolean isUserCredential) {
187: assert className != null;
188: assert w != null;
189: this .className = className;
190: this .w = w;
191: this .sampleSelected = sampleSelected;
192: this .isSecurityChecked = isSecurityChecked;
193: this .isSampleCredential = isSampleCredential;
194: this .userName = userName;
195: this .userPassword = userPassword;
196: this .url = url;
197: this .isUserCredential = isUserCredential;
198: }
199:
200: //Called for every method in the java source file
201: @Override
202: public Void visitMethod(MethodTree tree, Object p) {
203: //Obtain the owner of this method, getCurrentPath() returns a path from root (CompilationUnitTree) to current node (tree)
204: ClassTree owner = (ClassTree) getCurrentPath()
205: .getParentPath().getLeaf();
206: //Is it the generated class, for the case when the template has more classes
207: if (className.contentEquals(owner.getSimpleName())) {
208: //is this method a main method
209: //Get the Element for this method tree - Trees.getElement(TreePath)
210: ExecutableElement e = (ExecutableElement) w.getTrees()
211: .getElement(getCurrentPath());
212: TreeMaker treeMaker = w.getTreeMaker();
213: if (JavaModelHelper.isMain(e)) {
214: List<? extends StatementTree> statements = tree
215: .getBody().getStatements();
216: List<StatementTree> newStatements = new ArrayList<StatementTree>(
217: statements);
218: IdentifierTree managerField = w.getTreeMaker()
219: .Identifier("manager");// NOI18N
220: MemberSelectTree closeSelect = treeMaker
221: .MemberSelect(managerField, "close");// NOI18N
222: MethodInvocationTree closeInvokation = treeMaker
223: .MethodInvocation(
224: Collections
225: .<ExpressionTree> emptyList(),
226: closeSelect,
227: Collections
228: .<ExpressionTree> emptyList());
229:
230: ExpressionStatementTree t = treeMaker
231: .ExpressionStatement(closeInvokation);
232: if (sampleSelected) {
233: JavaModelHelper
234: .addCommentPrefixedByWhiteLine(
235: treeMaker, t,
236: Comment.Style.LINE,
237: "SAMPLE MBEAN NAME DISCOVERY. Uncomment following code."); // NOI18N
238: JavaModelHelper.addCommentFollowedByWhiteLine(
239: treeMaker, t, Comment.Style.BLOCK, "\n"
240: + // NOI18N
241: " Set resultSet = \n"
242: + // NOI18N
243: " manager.getMBeanServerConnection().queryNames(null, null);\n"
244: + // NOI18N
245: " for(Iterator i = resultSet.iterator(); i.hasNext();) {\n"
246: + // NOI18N
247: " System.out.println(\"MBean name: \" + i.next());\n"
248: + // NOI18N
249: " }\n");// NOI18N
250: } else {
251: JavaModelHelper
252: .addCommentSurroundedByWhiteLine(
253: treeMaker, t,
254: Comment.Style.LINE,
255: " TODO add your Management Logic");// NOI18N
256: }
257: JavaModelHelper.addComment(treeMaker, t,
258: Comment.Style.LINE, " Close connection"); // NOI18N
259: newStatements.add((StatementTree) t);
260: // Add System.out.println
261: IdentifierTree systemField = treeMaker
262: .Identifier("System");// NOI18N
263: MemberSelectTree outSelect = treeMaker
264: .MemberSelect(systemField, "out");// NOI18N
265: MemberSelectTree printlnSelect = treeMaker
266: .MemberSelect(outSelect, "println");// NOI18N
267: LiteralTree msgValTree = treeMaker
268: .Literal("Connection closed.");// NOI18N
269: List<ExpressionTree> params = new ArrayList<ExpressionTree>(
270: 1);
271: params.add(msgValTree);
272: MethodInvocationTree printlnInvokation = treeMaker
273: .MethodInvocation(Collections
274: .<ExpressionTree> emptyList(),
275: printlnSelect, params);
276:
277: ExpressionStatementTree t2 = treeMaker
278: .ExpressionStatement(printlnInvokation);
279: newStatements.add((StatementTree) t2);
280:
281: BlockTree newBody = treeMaker.Block(newStatements,
282: false);
283: w.rewrite(tree.getBody(), newBody);
284: } else {
285: if (e.getSimpleName().toString().equals("connect")) {// NOI18N
286: // List<? extends StatementTree> statements = tree.getBody().getStatements();
287: // List<StatementTree> newStatements = new ArrayList<StatementTree>(statements);
288: List<StatementTree> newStatements = new ArrayList<StatementTree>();
289:
290: IdentifierTree connectorField = w
291: .getTreeMaker().Identifier("connector");// NOI18N
292: MemberSelectTree getMBSCSelect = treeMaker
293: .MemberSelect(connectorField,
294: "getMBeanServerConnection");// NOI18N
295: MethodInvocationTree getMBSCInvokation = treeMaker
296: .MethodInvocation(
297: Collections
298: .<ExpressionTree> emptyList(),
299: getMBSCSelect,
300: Collections
301: .<ExpressionTree> emptyList());
302:
303: IdentifierTree mbscField = w.getTreeMaker()
304: .Identifier("mbsc");// NOI18N
305: AssignmentTree bt = treeMaker.Assignment(
306: mbscField, getMBSCInvokation);
307:
308: ExpressionStatementTree t = treeMaker
309: .ExpressionStatement(bt);
310: JavaModelHelper.addComment(treeMaker, t,
311: Comment.Style.LINE,
312: " Get the MBeanServerConnection"); // NOI18N
313:
314: fillURL(treeMaker, newStatements);
315:
316: fillUserCredentials(treeMaker, newStatements);
317:
318: fillConnector(treeMaker, newStatements);
319:
320: newStatements.add((StatementTree) t);
321:
322: BlockTree newBody = treeMaker.Block(
323: newStatements, false);
324: w.rewrite(tree.getBody(), newBody);
325: }
326: }
327: }
328: super .visitMethod(tree, p);
329: return null;
330: }
331:
332: private void fillUserCredentials(TreeMaker treeMaker,
333: List<StatementTree> newStatements) {
334: if (isSecurityChecked && !isSampleCredential) {
335: TypeElement hashMapClass = w.getElements()
336: .getTypeElement("java.util.HashMap");// NOI18N
337: ExpressionTree hashMapEx = treeMaker
338: .QualIdent(hashMapClass);
339: TypeElement mapClass = w.getElements().getTypeElement(
340: "java.util.Map");// NOI18N
341: ExpressionTree mapEx = treeMaker.QualIdent(mapClass);
342:
343: NewClassTree mapConstructor = treeMaker.NewClass(null,
344: Collections.<ExpressionTree> emptyList(),
345: hashMapEx, Collections
346: .<ExpressionTree> emptyList(), null);
347: VariableTree vt = treeMaker.Variable(treeMaker
348: .Modifiers(Collections.<Modifier> emptySet(),
349: Collections
350: .<AnnotationTree> emptyList()),
351: "env", mapEx, mapConstructor);// NOI18N
352:
353: newStatements.add(vt);
354:
355: List<ExpressionTree> putParams = new ArrayList<ExpressionTree>(
356: 2);
357:
358: IdentifierTree envField = treeMaker.Identifier("env");// NOI18N
359: MemberSelectTree putSelect = treeMaker.MemberSelect(
360: envField, "put");// NOI18N
361:
362: TypeElement connectorClass = w.getElements()
363: .getTypeElement(
364: "javax.management.remote.JMXConnector");// NOI18N
365: ExpressionTree connectorTree = treeMaker
366: .QualIdent(connectorClass);
367:
368: MemberSelectTree credSelect = treeMaker.MemberSelect(
369: connectorTree, "CREDENTIALS");// NOI18N
370:
371: putParams.add(credSelect);
372:
373: TypeElement stringClass = w.getElements()
374: .getTypeElement("java.lang.String");// NOI18N
375: ExpressionTree stringEx = treeMaker
376: .QualIdent(stringClass);
377: LiteralTree user = treeMaker.Literal(userName);
378: LiteralTree userP = treeMaker.Literal(userPassword);
379: List<ExpressionTree> arrayInit = new ArrayList<ExpressionTree>(
380: 2);
381: arrayInit.add(user);
382: arrayInit.add(userP);
383: NewArrayTree arrayTree = treeMaker.NewArray(stringEx,
384: Collections.<ExpressionTree> emptyList(),
385: arrayInit);
386: putParams.add(arrayTree);
387:
388: MethodInvocationTree putInvokation = treeMaker
389: .MethodInvocation(Collections
390: .<ExpressionTree> emptyList(),
391: putSelect, putParams);
392:
393: ExpressionStatementTree t = treeMaker
394: .ExpressionStatement(putInvokation);
395: newStatements.add(t);
396: }
397: }
398:
399: private void fillURL(TreeMaker treeMaker,
400: List<StatementTree> newStatements) {
401: TypeElement urlClass = w.getElements().getTypeElement(
402: "javax.management.remote.JMXServiceURL");// NOI18N
403: ExpressionTree urlTree = treeMaker.QualIdent(urlClass);
404: List<ExpressionTree> ctrParams = new ArrayList<ExpressionTree>(
405: 1);
406: ctrParams.add(treeMaker.Literal(url));
407:
408: NewClassTree urlConstructor = treeMaker.NewClass(null,
409: Collections.<ExpressionTree> emptyList(), urlTree,
410: ctrParams, null);
411:
412: VariableTree vt = treeMaker.Variable(treeMaker.Modifiers(
413: Collections.<Modifier> emptySet(), Collections
414: .<AnnotationTree> emptyList()), "url",
415: urlTree, urlConstructor);// NOI18N
416: JavaModelHelper.addComment(treeMaker, vt,
417: Comment.Style.LINE, " Create JMX Agent URL");// NOI18N
418: newStatements.add(vt);
419: }
420:
421: private void fillConnector(TreeMaker treeMaker,
422: List<StatementTree> newStatements) {
423: TypeElement factoryClass = w.getElements().getTypeElement(
424: "javax.management.remote.JMXConnectorFactory");// NOI18N
425: ExpressionTree factoryTree = treeMaker
426: .QualIdent(factoryClass);
427: MemberSelectTree connectSelect = treeMaker.MemberSelect(
428: factoryTree, "connect");// NOI18N
429: List<ExpressionTree> connectParams = new ArrayList<ExpressionTree>(
430: 1);
431: connectParams.add(treeMaker.Identifier("url"));// NOI18N
432:
433: if (isSecurityChecked && isUserCredential)
434: connectParams.add(treeMaker.Identifier("env"));// NOI18N
435: else
436: connectParams.add(treeMaker.Literal(null));
437:
438: MethodInvocationTree connectInvokation = treeMaker
439: .MethodInvocation(Collections
440: .<ExpressionTree> emptyList(),
441: connectSelect, connectParams);
442:
443: IdentifierTree connectorField = w.getTreeMaker()
444: .Identifier("connector");// NOI18N
445: AssignmentTree bt = treeMaker.Assignment(connectorField,
446: connectInvokation);
447:
448: ExpressionStatementTree t = treeMaker
449: .ExpressionStatement(bt);
450: newStatements.add((StatementTree) t);
451: if (isSecurityChecked && isSampleCredential) {
452: JavaModelHelper
453: .addCommentPrefixedByWhiteLine(treeMaker, t,
454: Comment.Style.BLOCK,
455: "\n SAMPLE CREDENTIALS. Uncomment following code. \n"
456: + // NOI18N
457: " Replace userName and userPassword with your parameters. \n"
458: + // NOI18N
459: " Provide env parameter when calling JMXConnectorFactory.connect(url, env)\n\n");// NOI18N
460:
461: JavaModelHelper.addCommentFollowedByWhiteLine(
462: treeMaker, t, Comment.Style.BLOCK, "\n"
463: + // NOI18N
464: "Map env = new HashMap(); \n"
465: + // NOI18N
466: "env.put(JMXConnector.CREDENTIALS, new String[]{\""
467: + // NOI18N
468: "userName\", \"" + // NOI18N
469: "userPassword" + // NOI18N
470: "\"});\n");// NOI18N
471: }
472: JavaModelHelper.addComment(treeMaker, t,
473: Comment.Style.LINE, " Connect the JMXConnector"); // NOI18N
474: }
475: }
476: }
|