├── .gitattributes
├── .gitignore
├── LICENSE.md
├── README.md
├── mybatipse-feature
├── .project
├── build.properties
└── feature.xml
├── mybatipse
├── .classpath
├── .options
├── .project
├── .settings
│ ├── org.eclipse.jdt.core.prefs
│ └── org.eclipse.jdt.ui.prefs
├── META-INF
│ └── MANIFEST.MF
├── build.properties
├── icons
│ ├── mybatis-alias.png
│ ├── mybatis-ns.png
│ ├── mybatis.png
│ └── mybatis32.png
├── plugin.xml
└── src
│ └── net
│ └── harawata
│ └── mybatipse
│ ├── Activator.java
│ ├── MybatipseConstants.java
│ ├── MybatipseResourceChangeListener.java
│ ├── apt
│ └── MybatipseAnnotationProcessorFactory.java
│ ├── bean
│ ├── BeanPropertyCache.java
│ ├── BeanPropertyInfo.java
│ ├── BeanPropertyVisitor.java
│ ├── JavaCompletionProposal.java
│ └── SupertypeHierarchyCache.java
│ ├── cache
│ └── JavaMapperCache.java
│ ├── console
│ ├── CopyLogStatementHandler.java
│ └── MybatisLogBinder.java
│ ├── hyperlink
│ ├── HyperlinkDetector.java
│ ├── JavaHyperlinkDetector.java
│ ├── ToJavaHyperlink.java
│ ├── ToXmlHyperlink.java
│ └── XmlHyperlinkDetector.java
│ ├── mybatis
│ ├── ConfigRegistry.java
│ ├── ExpressionProposalParser.java
│ ├── JavaCompletionProposalComputer.java
│ ├── JavaMapperUtil.java
│ ├── MapperNamespaceCache.java
│ ├── MybatipseXmlUtil.java
│ ├── ProposalComputorHelper.java
│ ├── TypeAliasCache.java
│ ├── TypeAliasMap.java
│ ├── ValidatorHelper.java
│ ├── XmlCompletionProposalComputer.java
│ └── XmlValidator.java
│ ├── nature
│ ├── MyBatisNature.java
│ ├── MybatipseIncrementalBuilder.java
│ └── ToggleNatureCommand.java
│ ├── preference
│ ├── CustomTypeAliasListEditor.java
│ ├── EntryModifiableListEditor.java
│ ├── MybatipsePreferenceInitializer.java
│ ├── MybatipsePreferencePage.java
│ └── ScopedFieldEditorPreferencePage.java
│ ├── quickassist
│ ├── AddParamQuickAssist.java
│ ├── JavaQuickAssistProcessor.java
│ ├── MoveResultMapToXmlQuickAssist.java
│ ├── MoveStatementToXmlQuickAssist.java
│ └── QuickAssistCompletionProposal.java
│ ├── refactoring
│ ├── ElementRenameInfo.java
│ ├── ElementRenameRefactoring.java
│ ├── JavaRefactoringPropertyTester.java
│ ├── MapperMethodRenameParticipant.java
│ ├── XmlAttrEditRequestor.java
│ ├── collector
│ │ ├── RenameEditCollector.java
│ │ ├── ResultMapRenameEditCollector.java
│ │ ├── SqlRenameEditCollector.java
│ │ └── StatementRenameEditCollector.java
│ ├── handler
│ │ ├── ElementRenameHandler.java
│ │ ├── JavaElementRenameHandler.java
│ │ └── XmlElementRenameHandler.java
│ └── wizard
│ │ ├── ElementRenameWizard.java
│ │ └── ElementRenameWizardPage.java
│ ├── util
│ ├── NameUtil.java
│ └── XpathUtil.java
│ ├── view
│ └── MyBatisSqlView.java
│ └── wizard
│ ├── NewXmlMapperWizard.java
│ └── NewXmlMapperWizardPage.java
└── screen
├── ac-class-cc.png
├── ac-class.png
├── ac-jdbc-type.png
├── ac-ns1.png
├── ac-ns2.png
├── ac-options-keyprop-java.png
├── ac-prop-test.png
├── ac-prop1.png
├── ac-prop2.png
├── ac-ref.png
├── ac-result-prop-java.png
├── ac-results.png
├── ac-rmap-java.png
├── ac-select-java.png
├── ac-selkey-keyprop-java.png
├── ac-setting-name.png
├── ac-setting-value.png
├── ac-stmt-prop-java.png
├── ac-stmt-prop-xml.png
├── ac-stmt.png
├── actual-parameters.png
├── err-refid.png
├── hl-java-method.png
├── hl-refid.png
├── hl-xml-mapper.png
├── hl-xml-statement.png
├── nature.png
├── prblm-view.png
├── pref-alias.png
├── qa-add-param1.png
├── qa-add-param2.png
├── qa-copy-statement.png
├── qa-move-resultmap.png
├── qa-move-statement.png
├── refactor-rename-java.png
├── refactor-rename-xml.png
├── smart-copy-console.png
├── sqlview-xml.png
├── sqlview.png
├── wizard-xml-mapper.png
└── xml-proposal-order.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behaviour, in case users don't have core.autocrlf set.
2 | * text=auto
3 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
--------------------------------------------------------------------------------
/mybatipse-feature/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | mybatipse-feature
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.pde.FeatureBuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.pde.FeatureNature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/mybatipse-feature/build.properties:
--------------------------------------------------------------------------------
1 | bin.includes = feature.xml
2 |
--------------------------------------------------------------------------------
/mybatipse/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/mybatipse/.options:
--------------------------------------------------------------------------------
1 | # Enable verbose logging.
2 | net.harawata.mybatipse/debug=true
3 |
4 | # Bean property cache activities.
5 | net.harawata.mybatipse/debug/beanPropertyCache=false
6 |
--------------------------------------------------------------------------------
/mybatipse/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | mybatipse
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.pde.ManifestBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.pde.SchemaBuilder
20 |
21 |
22 |
23 |
24 | org.eclipse.pde.api.tools.apiAnalysisBuilder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.pde.PluginNature
31 | org.eclipse.jdt.core.javanature
32 | org.eclipse.pde.api.tools.apiAnalysisNature
33 |
34 |
35 |
--------------------------------------------------------------------------------
/mybatipse/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
3 | formatter_profile=_net.harawata.formatter
4 | formatter_settings_version=12
5 | org.eclipse.jdt.ui.javadoc=true
6 | org.eclipse.jdt.ui.text.custom_code_templates=/**\n * @return the ${bare_field_name}\n *//**\n * @param ${param} the ${bare_field_name} to set\n *//**\n * ${tags}\n *//*-******************************************************************************\n * Copyright (c) ${year} ${user}.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * ${user} - initial API and implementation and/or initial documentation\n *******************************************************************************/\n/**\n * @author ${user}\n * ${tags}\n *//**\n * \n *//**\n * ${tags}\n *//**\n * ${tags}\n * ${see_to_target}\n */${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}\n\n\n\n// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();// ${todo} Auto-generated method stub\n${body_statement}${body_statement}\n// ${todo} Auto-generated constructor stubreturn ${field};${field} \= ${param};
7 | sp_cleanup.add_default_serial_version_id=true
8 | sp_cleanup.add_generated_serial_version_id=false
9 | sp_cleanup.add_missing_annotations=true
10 | sp_cleanup.add_missing_deprecated_annotations=true
11 | sp_cleanup.add_missing_methods=false
12 | sp_cleanup.add_missing_nls_tags=false
13 | sp_cleanup.add_missing_override_annotations=true
14 | sp_cleanup.add_missing_override_annotations_interface_methods=true
15 | sp_cleanup.add_serial_version_id=false
16 | sp_cleanup.always_use_blocks=true
17 | sp_cleanup.always_use_parentheses_in_expressions=false
18 | sp_cleanup.always_use_this_for_non_static_field_access=false
19 | sp_cleanup.always_use_this_for_non_static_method_access=false
20 | sp_cleanup.convert_to_enhanced_for_loop=false
21 | sp_cleanup.correct_indentation=false
22 | sp_cleanup.format_source_code=true
23 | sp_cleanup.format_source_code_changes_only=false
24 | sp_cleanup.make_local_variable_final=false
25 | sp_cleanup.make_parameters_final=false
26 | sp_cleanup.make_private_fields_final=true
27 | sp_cleanup.make_type_abstract_if_missing_method=false
28 | sp_cleanup.make_variable_declarations_final=true
29 | sp_cleanup.never_use_blocks=false
30 | sp_cleanup.never_use_parentheses_in_expressions=true
31 | sp_cleanup.on_save_use_additional_actions=false
32 | sp_cleanup.organize_imports=true
33 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
34 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
35 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
36 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
37 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
38 | sp_cleanup.remove_private_constructors=true
39 | sp_cleanup.remove_trailing_whitespaces=false
40 | sp_cleanup.remove_trailing_whitespaces_all=true
41 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
42 | sp_cleanup.remove_unnecessary_casts=true
43 | sp_cleanup.remove_unnecessary_nls_tags=false
44 | sp_cleanup.remove_unused_imports=false
45 | sp_cleanup.remove_unused_local_variables=false
46 | sp_cleanup.remove_unused_private_fields=true
47 | sp_cleanup.remove_unused_private_members=false
48 | sp_cleanup.remove_unused_private_methods=true
49 | sp_cleanup.remove_unused_private_types=true
50 | sp_cleanup.sort_members=false
51 | sp_cleanup.sort_members_all=false
52 | sp_cleanup.use_blocks=false
53 | sp_cleanup.use_blocks_only_for_return_and_throw=false
54 | sp_cleanup.use_parentheses_in_expressions=false
55 | sp_cleanup.use_this_for_non_static_field_access=false
56 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
57 | sp_cleanup.use_this_for_non_static_method_access=false
58 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
59 |
--------------------------------------------------------------------------------
/mybatipse/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Bundle-ManifestVersion: 2
3 | Bundle-Name: MyBatipse
4 | Bundle-SymbolicName: net.harawata.mybatipse;singleton:=true
5 | Bundle-Version: 1.3.1.qualifier
6 | Bundle-Activator: net.harawata.mybatipse.Activator
7 | Bundle-Vendor: Iwao AVE!
8 | Require-Bundle: org.eclipse.core.runtime,
9 | org.eclipse.jface.text,
10 | org.eclipse.wst.sse.ui;bundle-version="1.2.0",
11 | org.eclipse.wst.xml.core,
12 | org.eclipse.wst.sse.core,
13 | org.eclipse.wst.xml.ui,
14 | org.eclipse.ui,
15 | org.eclipse.ui.ide,
16 | org.eclipse.core.resources,
17 | org.eclipse.jdt.core;bundle-version="3.24.0",
18 | org.eclipse.jdt.ui,
19 | org.eclipse.ui.workbench.texteditor,
20 | org.eclipse.wst.validation,
21 | org.eclipse.jdt.apt.core,
22 | org.eclipse.jdt.apt.pluggable.core,
23 | org.eclipse.ltk.core.refactoring,
24 | org.eclipse.ltk.ui.refactoring,
25 | org.eclipse.search,
26 | org.eclipse.jdt.core.manipulation,
27 | org.eclipse.core.expressions
28 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8
29 | Bundle-ActivationPolicy: lazy
30 | Automatic-Module-Name: net.harawata.mybatipse
31 |
--------------------------------------------------------------------------------
/mybatipse/build.properties:
--------------------------------------------------------------------------------
1 | source.. = src/
2 | output.. = bin/
3 | bin.includes = plugin.xml,\
4 | META-INF/,\
5 | .,\
6 | icons/,\
7 | .options
8 |
--------------------------------------------------------------------------------
/mybatipse/icons/mybatis-alias.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/mybatipse/icons/mybatis-alias.png
--------------------------------------------------------------------------------
/mybatipse/icons/mybatis-ns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/mybatipse/icons/mybatis-ns.png
--------------------------------------------------------------------------------
/mybatipse/icons/mybatis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/mybatipse/icons/mybatis.png
--------------------------------------------------------------------------------
/mybatipse/icons/mybatis32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/mybatipse/icons/mybatis32.png
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/Activator.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import org.eclipse.core.resources.IProject;
17 | import org.eclipse.core.resources.IResourceChangeEvent;
18 | import org.eclipse.core.resources.IResourceChangeListener;
19 | import org.eclipse.core.resources.IWorkspace;
20 | import org.eclipse.core.resources.ProjectScope;
21 | import org.eclipse.core.resources.ResourcesPlugin;
22 | import org.eclipse.core.runtime.Status;
23 | import org.eclipse.core.runtime.preferences.InstanceScope;
24 | import org.eclipse.jface.dialogs.MessageDialog;
25 | import org.eclipse.jface.preference.IPreferenceStore;
26 | import org.eclipse.jface.resource.ImageDescriptor;
27 | import org.eclipse.jface.util.IPropertyChangeListener;
28 | import org.eclipse.jface.util.PropertyChangeEvent;
29 | import org.eclipse.swt.SWT;
30 | import org.eclipse.swt.graphics.Image;
31 | import org.eclipse.swt.widgets.Display;
32 | import org.eclipse.swt.widgets.Shell;
33 | import org.eclipse.ui.plugin.AbstractUIPlugin;
34 | import org.eclipse.ui.preferences.ScopedPreferenceStore;
35 | import org.osgi.framework.BundleContext;
36 |
37 | import net.harawata.mybatipse.mybatis.TypeAliasCache;
38 | import net.harawata.mybatipse.preference.ScopedFieldEditorPreferencePage;
39 |
40 | /**
41 | * @author Iwao AVE!
42 | */
43 | public class Activator extends AbstractUIPlugin
44 | {
45 | private static Activator plugin;
46 |
47 | private IResourceChangeListener resourceChangeListener;
48 |
49 | public Activator()
50 | {
51 | }
52 |
53 | public void start(BundleContext context) throws Exception
54 | {
55 | super.start(context);
56 |
57 | IWorkspace workspace = ResourcesPlugin.getWorkspace();
58 | resourceChangeListener = new MybatipseResourceChangeListener();
59 | workspace.addResourceChangeListener(resourceChangeListener,
60 | IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_BUILD);
61 |
62 | plugin = this;
63 | }
64 |
65 | public void stop(BundleContext context) throws Exception
66 | {
67 | plugin = null;
68 |
69 | IWorkspace workspace = ResourcesPlugin.getWorkspace();
70 | if (workspace != null && resourceChangeListener != null)
71 | {
72 | workspace.removeResourceChangeListener(resourceChangeListener);
73 | }
74 |
75 | super.stop(context);
76 | }
77 |
78 | public static Activator getDefault()
79 | {
80 | return plugin;
81 | }
82 |
83 | public static IPreferenceStore getPreferenceStore(final IProject project)
84 | {
85 | ScopedPreferenceStore store = null;
86 | if (project != null)
87 | {
88 | store = new ScopedPreferenceStore(new ProjectScope(project), PLUGIN_ID);
89 | }
90 | if (store == null
91 | || !store.getBoolean(ScopedFieldEditorPreferencePage.USE_PROJECT_SETTINGS))
92 | {
93 | store = new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_ID);
94 | }
95 | store.addPropertyChangeListener(new IPropertyChangeListener()
96 | {
97 | @Override
98 | public void propertyChange(PropertyChangeEvent event)
99 | {
100 | if (project == null)
101 | TypeAliasCache.getInstance().clear();
102 | else
103 | TypeAliasCache.getInstance().remove(project);
104 | }
105 | });
106 | return store;
107 | }
108 |
109 | public static ImageDescriptor getImageDescriptor(String path)
110 | {
111 | return imageDescriptorFromPlugin(PLUGIN_ID, path);
112 | }
113 |
114 | public static Image getIcon()
115 | {
116 | return getImageDescriptor("/icons/mybatis.png").createImage(); //$NON-NLS-1$
117 | }
118 |
119 | public static Image getIcon(String path)
120 | {
121 | return getImageDescriptor(path).createImage();
122 | }
123 |
124 | public static void log(Status status)
125 | {
126 | if (getDefault() != null && getDefault().getLog() != null)
127 | getDefault().getLog().log(status);
128 | }
129 |
130 | public static void log(int severity, String message)
131 | {
132 | log(new Status(severity, PLUGIN_ID, message));
133 | }
134 |
135 | public static void log(int severity, String message, Throwable t)
136 | {
137 | log(severity, 0, message, t);
138 | }
139 |
140 | public static void log(int severity, int code, String message, Throwable t)
141 | {
142 | log(new Status(severity, PLUGIN_ID, code, message, t));
143 | }
144 |
145 | public static boolean openDialog(int kind, String title, String message)
146 | {
147 | Shell shell = Display.getDefault().getActiveShell();
148 | return MessageDialog.open(kind, shell, title, message, SWT.SHEET);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/MybatipseConstants.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse;
13 |
14 | import java.util.Arrays;
15 | import java.util.List;
16 |
17 | import org.eclipse.core.runtime.Platform;
18 | import org.eclipse.core.runtime.content.IContentType;
19 | import org.eclipse.core.runtime.content.IContentTypeManager;
20 |
21 | /**
22 | * @author Iwao AVE!
23 | */
24 | public class MybatipseConstants
25 | {
26 | public static final String PLUGIN_ID = "net.harawata.mybatipse"; //$NON-NLS-1$
27 |
28 | public static final String CONTENT_TYPE_CONFIG = "net.harawata.mybatipse.config"; //$NON-NLS-1$
29 |
30 | public static final String CONTENT_TYPE_MAPPER = "net.harawata.mybatipse.mapper"; //$NON-NLS-1$
31 |
32 | public static final String CONTENT_TYPE_SPRING_CONFIG = "net.harawata.mybatipse.springConfig"; //$NON-NLS-1$
33 |
34 | public static final String CONTENT_TYPE_SPRING_CONFIG_STS = "com.springsource.sts.config.ui.beanConfigFile"; //$NON-NLS-1$
35 |
36 | public static final String PREF_CUSTOM_TYPE_ALIASES = "prefCustomTypeAliases"; //$NON-NLS-1$
37 |
38 | public static final String DEBUG_BEAN_PROPERTY_CACHE = PLUGIN_ID + "/debug/beanPropertyCache";
39 |
40 | public static final String ANNOTATION_SELECT = "org.apache.ibatis.annotations.Select";
41 |
42 | public static final String ANNOTATION_SELECT_PROVIDER = "org.apache.ibatis.annotations.SelectProvider";
43 |
44 | public static final String ANNOTATION_INSERT_PROVIDER = "org.apache.ibatis.annotations.InsertProvider";
45 |
46 | public static final String ANNOTATION_UPDATE_PROVIDER = "org.apache.ibatis.annotations.UpdateProvider";
47 |
48 | public static final String ANNOTATION_DELETE_PROVIDER = "org.apache.ibatis.annotations.DeleteProvider";
49 |
50 | public static final String ANNOTATION_UPDATE = "org.apache.ibatis.annotations.Update";
51 |
52 | public static final String ANNOTATION_INSERT = "org.apache.ibatis.annotations.Insert";
53 |
54 | public static final String ANNOTATION_DELETE = "org.apache.ibatis.annotations.Delete";
55 |
56 | public static final String ANNOTATION_RESULTS = "org.apache.ibatis.annotations.Results";
57 |
58 | public static final String ANNOTATION_RESULT = "org.apache.ibatis.annotations.Result";
59 |
60 | public static final String ANNOTATION_PARAM = "org.apache.ibatis.annotations.Param";
61 |
62 | public static final String ANNOTATION_RESULT_MAP = "org.apache.ibatis.annotations.ResultMap";
63 |
64 | public static final String ANNOTATION_ONE = "org.apache.ibatis.annotations.One";
65 |
66 | public static final String ANNOTATION_MANY = "org.apache.ibatis.annotations.Many";
67 |
68 | public static final String ANNOTATION_MAP_KEY = "org.apache.ibatis.annotations.MapKey";
69 |
70 | public static final List STATEMENT_ANNOTATIONS = Arrays.asList(ANNOTATION_SELECT,
71 | ANNOTATION_INSERT, ANNOTATION_UPDATE, ANNOTATION_DELETE, ANNOTATION_SELECT_PROVIDER,
72 | ANNOTATION_INSERT_PROVIDER, ANNOTATION_UPDATE_PROVIDER, ANNOTATION_DELETE_PROVIDER);
73 |
74 | public static final List PROVIDER_ANNOTATIONS = Arrays.asList(
75 | ANNOTATION_SELECT_PROVIDER, ANNOTATION_INSERT_PROVIDER, ANNOTATION_UPDATE_PROVIDER,
76 | ANNOTATION_DELETE_PROVIDER);
77 |
78 | public static final List PROVIDER_ANNOTATION_NAMES = Arrays.asList("SelectProvider",
79 | "InsertProvider", "UpdateProvider", "DeleteProvider");
80 |
81 | public static final String TYPE_ROW_BOUNDS = "org.apache.ibatis.session.RowBounds";
82 |
83 | public static final String TYPE_TYPE_HANDLER = "org.apache.ibatis.type.TypeHandler";
84 |
85 | public static final String TYPE_CACHE = "org.apache.ibatis.cache.Cache";
86 |
87 | public static final String TYPE_OBJECT_FACTORY = "org.apache.ibatis.reflection.factory.ObjectFactory";
88 |
89 | public static final String TYPE_OBJECT_WRAPPER_FACTORY = "org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory";
90 |
91 | public static final String TYPE_REFLECTOR_FACTORY = "org.apache.ibatis.reflection.ReflectorFactory";
92 |
93 | public static final String TYPE_VFS = "org.apache.ibatis.io.VFS";
94 |
95 | public static final String TYPE_LANGUAGE_DRIVER = "org.apache.ibatis.scripting.LanguageDriver";
96 |
97 | public static final String GUICE_MYBATIS_MODULE = "org.mybatis.guice.MyBatisModule";
98 |
99 | public static final String SPRING_SQL_SESSION_FACTORY_BEAN = "org.mybatis.spring.SqlSessionFactoryBean";
100 |
101 | public static final IContentType mapperContentType;
102 |
103 | public static final IContentType configContentType;
104 |
105 | public static IContentType springConfigContentType;
106 |
107 | static
108 | {
109 | IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
110 | mapperContentType = contentTypeManager.getContentType(CONTENT_TYPE_MAPPER);
111 | configContentType = contentTypeManager.getContentType(CONTENT_TYPE_CONFIG);
112 | springConfigContentType = contentTypeManager.getContentType(CONTENT_TYPE_SPRING_CONFIG);
113 | if (springConfigContentType == null)
114 | {
115 | // this means STS is installed...I guess.
116 | springConfigContentType = contentTypeManager
117 | .getContentType(CONTENT_TYPE_SPRING_CONFIG_STS);
118 | }
119 | }
120 |
121 | private MybatipseConstants()
122 | {
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/MybatipseResourceChangeListener.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import org.eclipse.core.resources.IFile;
17 | import org.eclipse.core.resources.IProject;
18 | import org.eclipse.core.resources.IResource;
19 | import org.eclipse.core.resources.IResourceChangeEvent;
20 | import org.eclipse.core.resources.IResourceChangeListener;
21 | import org.eclipse.core.resources.IResourceDelta;
22 | import org.eclipse.core.resources.IResourceDeltaVisitor;
23 | import org.eclipse.core.resources.IWorkspace;
24 | import org.eclipse.core.resources.IncrementalProjectBuilder;
25 | import org.eclipse.core.runtime.CoreException;
26 | import org.eclipse.core.runtime.Status;
27 | import org.eclipse.core.runtime.content.IContentDescription;
28 | import org.eclipse.core.runtime.content.IContentType;
29 | import org.eclipse.jdt.core.ICompilationUnit;
30 | import org.eclipse.jdt.core.IJavaProject;
31 | import org.eclipse.jdt.core.IType;
32 | import org.eclipse.jdt.core.JavaCore;
33 |
34 | import net.harawata.mybatipse.bean.BeanPropertyCache;
35 | import net.harawata.mybatipse.bean.SupertypeHierarchyCache;
36 | import net.harawata.mybatipse.cache.JavaMapperCache;
37 | import net.harawata.mybatipse.mybatis.ConfigRegistry;
38 | import net.harawata.mybatipse.mybatis.MapperNamespaceCache;
39 | import net.harawata.mybatipse.mybatis.TypeAliasCache;
40 |
41 | /**
42 | * @author Iwao AVE!
43 | */
44 | public class MybatipseResourceChangeListener implements IResourceChangeListener
45 | {
46 | public void resourceChanged(IResourceChangeEvent event)
47 | {
48 | if (event.getType() == IResourceChangeEvent.PRE_BUILD
49 | && event.getBuildKind() == IncrementalProjectBuilder.CLEAN_BUILD)
50 | {
51 | Object source = event.getSource();
52 | if (source instanceof IWorkspace)
53 | {
54 | ConfigRegistry.getInstance().clear();
55 | MapperNamespaceCache.getInstance().clear();
56 | BeanPropertyCache.clearBeanPropertyCache();
57 | JavaMapperCache.getInstance().clear();
58 | }
59 | else if (source instanceof IProject)
60 | {
61 | IProject project = (IProject)source;
62 | ConfigRegistry.getInstance().remove(project);
63 | MapperNamespaceCache.getInstance().remove(project);
64 | BeanPropertyCache.clearBeanPropertyCache(project);
65 | JavaMapperCache.getInstance().remove(project.getName());
66 | }
67 | }
68 | else if (event.getType() != IResourceChangeEvent.POST_CHANGE)
69 | return;
70 |
71 | IResourceDelta delta = event.getDelta();
72 | if (delta.getKind() == IResourceDelta.CHANGED
73 | && (delta.getFlags() == IResourceDelta.ENCODING
74 | || delta.getFlags() == IResourceDelta.MARKERS))
75 | return;
76 |
77 | IResourceDeltaVisitor visitor = new IResourceDeltaVisitor()
78 | {
79 | public boolean visit(IResourceDelta delta)
80 | {
81 | IResource resource = delta.getResource();
82 | if (resource.isDerived())
83 | return false;
84 |
85 | if (resource.getType() == IResource.FILE)
86 | {
87 | if (delta.getKind() == IResourceDelta.CHANGED
88 | && (delta.getFlags() == IResourceDelta.ENCODING
89 | || delta.getFlags() == IResourceDelta.MARKERS))
90 | return false;
91 |
92 | IProject project = resource.getProject();
93 | IFile file = (IFile)resource;
94 | if (!file.exists())
95 | return false;
96 | if ("xml".equals(file.getFileExtension()))
97 | {
98 | onXmlChange(delta, resource, project, file);
99 | return true;
100 | }
101 | else if ("java".equals(file.getFileExtension()))
102 | {
103 | onJavaChange(delta, project, file);
104 | return true;
105 | }
106 | }
107 | else if (resource.getType() == IResource.PROJECT)
108 | {
109 | if (delta.getKind() == IResourceDelta.REMOVED)
110 | {
111 | ConfigRegistry.getInstance().remove((IProject)resource);
112 | MapperNamespaceCache.getInstance().remove((IProject)resource);
113 | }
114 | }
115 | return true;
116 | }
117 |
118 | protected void onJavaChange(IResourceDelta delta, IProject project, IFile file)
119 | {
120 | ICompilationUnit compilationUnit = (ICompilationUnit)JavaCore.create(file);
121 | String elementName = compilationUnit.getElementName();
122 | String simpleTypeName = elementName.substring(0, elementName.length() - 5);
123 | IType type = compilationUnit.getType(simpleTypeName);
124 | IJavaProject javaProject = type.getJavaProject();
125 | if (javaProject == null)
126 | {
127 | return;
128 | }
129 | String qualifiedName = type.getFullyQualifiedName();
130 |
131 | BeanPropertyCache.clearBeanPropertyCache(project, qualifiedName);
132 | JavaMapperCache.getInstance().remove(javaProject, qualifiedName);
133 |
134 | if (SupertypeHierarchyCache.getInstance().isSubtype(type,
135 | MybatipseConstants.GUICE_MYBATIS_MODULE))
136 | {
137 | TypeAliasCache.getInstance().remove(project);
138 | }
139 | else if (delta.getKind() == IResourceDelta.REMOVED)
140 | {
141 | TypeAliasCache.getInstance().removeType(project.getName(), qualifiedName);
142 | }
143 | else
144 | {
145 | if (TypeAliasCache.getInstance().isInPackage(project.getName(), qualifiedName))
146 | {
147 | TypeAliasCache.getInstance().put(project.getName(), type, simpleTypeName);
148 | }
149 | }
150 | }
151 |
152 | protected void onXmlChange(IResourceDelta delta, IResource resource, IProject project,
153 | IFile file)
154 | {
155 | if (delta.getKind() == IResourceDelta.REMOVED || !file.exists())
156 | {
157 | // Cannot get content-type. Try removing the cache anyway.
158 | ConfigRegistry.getInstance().remove(project, file);
159 | MapperNamespaceCache.getInstance().remove(project.getName(), file);
160 | }
161 | else
162 | {
163 | try
164 | {
165 | IContentDescription contentDesc = file.getContentDescription();
166 | if (contentDesc != null)
167 | {
168 | IContentType contentType = contentDesc.getContentType();
169 | if (contentType != null)
170 | {
171 | if (contentType.isKindOf(configContentType)
172 | || contentType.isKindOf(springConfigContentType))
173 | {
174 | // In case there are multiple config files in the project,
175 | // just remove the currently registered config.
176 | ConfigRegistry.getInstance().remove(project);
177 | }
178 | else if (contentType.isKindOf(mapperContentType))
179 | {
180 | MapperNamespaceCache.getInstance().put(project.getName(), file);
181 | }
182 | }
183 | }
184 | }
185 | catch (CoreException e)
186 | {
187 | Activator.log(Status.ERROR, e.getMessage(), e);
188 | }
189 | }
190 | }
191 | };
192 | try
193 | {
194 | delta.accept(visitor);
195 | }
196 | catch (CoreException e)
197 | {
198 | Activator.log(Status.ERROR, e.getMessage(), e);
199 | }
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/bean/BeanPropertyInfo.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.bean;
13 |
14 | import java.util.Map;
15 |
16 | /**
17 | * @author Iwao AVE!
18 | */
19 | public class BeanPropertyInfo
20 | {
21 | private Map readableFields;
22 |
23 | private Map writableFields;
24 |
25 | public BeanPropertyInfo(
26 | Map readableFields,
27 | Map writableFields)
28 | {
29 | super();
30 | this.readableFields = readableFields;
31 | this.writableFields = writableFields;
32 | }
33 |
34 | public Map getReadableFields()
35 | {
36 | return readableFields;
37 | }
38 |
39 | public Map getWritableFields()
40 | {
41 | return writableFields;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/bean/BeanPropertyVisitor.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.bean;
13 |
14 | import java.beans.Introspector;
15 | import java.util.ArrayList;
16 | import java.util.Collections;
17 | import java.util.List;
18 | import java.util.Map;
19 | import java.util.Set;
20 | import java.util.concurrent.ConcurrentHashMap;
21 |
22 | import org.eclipse.jdt.core.IJavaProject;
23 | import org.eclipse.jdt.core.dom.ASTVisitor;
24 | import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
25 | import org.eclipse.jdt.core.dom.FieldDeclaration;
26 | import org.eclipse.jdt.core.dom.IMethodBinding;
27 | import org.eclipse.jdt.core.dom.ITypeBinding;
28 | import org.eclipse.jdt.core.dom.MethodDeclaration;
29 | import org.eclipse.jdt.core.dom.Modifier;
30 | import org.eclipse.jdt.core.dom.PrimitiveType;
31 | import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
32 | import org.eclipse.jdt.core.dom.Type;
33 | import org.eclipse.jdt.core.dom.TypeDeclaration;
34 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
35 |
36 | import net.harawata.mybatipse.util.NameUtil;
37 |
38 | /**
39 | * @author Iwao AVE!
40 | */
41 | public class BeanPropertyVisitor extends ASTVisitor
42 | {
43 | private IJavaProject project;
44 |
45 | private final String qualifiedName;
46 |
47 | private final List actualTypeParams;
48 |
49 | private final Map readableFields;
50 |
51 | private final Map writableFields;
52 |
53 | private final Map> subclassMap;
54 |
55 | private List typeParams = new ArrayList();
56 |
57 | private int nestLevel;
58 |
59 | public BeanPropertyVisitor(
60 | IJavaProject project,
61 | String qualifiedName,
62 | List actualTypeParams,
63 | Map readableFields,
64 | Map writableFields,
65 | Map> subclassMap)
66 | {
67 | super();
68 | this.project = project;
69 | this.qualifiedName = qualifiedName;
70 | this.actualTypeParams = actualTypeParams;
71 | this.readableFields = readableFields;
72 | this.writableFields = writableFields;
73 | this.subclassMap = subclassMap;
74 | }
75 |
76 | @Override
77 | public boolean visit(TypeDeclaration node)
78 | {
79 | ITypeBinding binding = node.resolveBinding();
80 | if (binding == null)
81 | return false;
82 |
83 | ITypeBinding[] args = binding.getTypeParameters();
84 | for (ITypeBinding arg : args)
85 | {
86 | typeParams.add(arg.getQualifiedName());
87 | }
88 |
89 | if (qualifiedName.equals(binding.getQualifiedName()))
90 | nestLevel = 1;
91 | else if (nestLevel > 0)
92 | nestLevel++;
93 |
94 | return true;
95 | }
96 |
97 | @Override
98 | public boolean visit(AnonymousClassDeclaration node)
99 | {
100 | return false;
101 | }
102 |
103 | @Override
104 | public boolean visit(FieldDeclaration node)
105 | {
106 | if (nestLevel != 1)
107 | return false;
108 | int modifiers = node.getModifiers();
109 | // Check modifers to spare binding overhead.
110 | if (Modifier.isPublic(modifiers) || !Modifier.isFinal(modifiers))
111 | {
112 | @SuppressWarnings("unchecked")
113 | List fragments = node.fragments();
114 | for (VariableDeclarationFragment fragment : fragments)
115 | {
116 | String fieldName = fragment.getName().toString();
117 | String qualifiedName = getQualifiedNameFromType(node.getType());
118 | if (qualifiedName != null)
119 | {
120 | if (Modifier.isPublic(modifiers))
121 | readableFields.put(fieldName,
122 | NameUtil.resolveTypeParam(actualTypeParams, typeParams, qualifiedName));
123 | if (!Modifier.isFinal(modifiers))
124 | writableFields.put(fieldName,
125 | NameUtil.resolveTypeParam(actualTypeParams, typeParams, qualifiedName));
126 | }
127 | }
128 | }
129 | return false;
130 | }
131 |
132 | @Override
133 | public boolean visit(MethodDeclaration node)
134 | {
135 | if (nestLevel != 1)
136 | return false;
137 | // Resolve binding first to support Lombok generated methods.
138 | // node.getModifiers() returns incorrect access modifiers for them.
139 | // https://github.com/harawata/stlipse/issues/2
140 | IMethodBinding method = node.resolveBinding();
141 | if (method != null && Modifier.isPublic(method.getModifiers()))
142 | {
143 | final String methodName = node.getName().toString();
144 | final int parameterCount = node.parameters().size();
145 | final Type returnType = node.getReturnType2();
146 | if (returnType == null)
147 | {
148 | // Ignore constructor
149 | }
150 | else if (isReturnVoid(returnType))
151 | {
152 | if (isSetter(methodName, parameterCount))
153 | {
154 | SingleVariableDeclaration param = (SingleVariableDeclaration)node.parameters().get(0);
155 | String qualifiedName = getQualifiedNameFromType(param.getType());
156 | String fieldName = getFieldNameFromAccessor(methodName);
157 | writableFields.put(fieldName,
158 | NameUtil.resolveTypeParam(actualTypeParams, typeParams, qualifiedName));
159 | }
160 | }
161 | else
162 | {
163 | if (isGetter(methodName, parameterCount))
164 | {
165 | String fieldName = getFieldNameFromAccessor(methodName);
166 | String qualifiedName = getQualifiedNameFromType(returnType);
167 | readableFields.put(fieldName,
168 | NameUtil.resolveTypeParam(actualTypeParams, typeParams, qualifiedName));
169 | }
170 | }
171 | }
172 | return false;
173 | }
174 |
175 | private String getQualifiedNameFromType(Type type)
176 | {
177 | ITypeBinding binding = type.resolveBinding();
178 | if (binding != null)
179 | {
180 | return binding.getQualifiedName();
181 | }
182 | return null;
183 | }
184 |
185 | public static boolean isGetter(String methodName, int parameterCount)
186 | {
187 | return (methodName.startsWith("get") && methodName.length() > 3)
188 | || (methodName.startsWith("is") && methodName.length() > 2) && parameterCount == 0;
189 | }
190 |
191 | public static boolean isSetter(String methodName, int parameterCount)
192 | {
193 | return methodName.startsWith("set") && methodName.length() > 3 && parameterCount == 1;
194 | }
195 |
196 | private boolean isReturnVoid(Type type)
197 | {
198 | return type.isPrimitiveType()
199 | && PrimitiveType.VOID.equals(((PrimitiveType)type).getPrimitiveTypeCode());
200 | }
201 |
202 | @Override
203 | public void endVisit(TypeDeclaration node)
204 | {
205 | if (nestLevel == 1)
206 | {
207 | Type superclassType = node.getSuperclassType();
208 | if (superclassType != null)
209 | {
210 | ITypeBinding binding = superclassType.resolveBinding();
211 | if (binding != null)
212 | {
213 | parseSuper(binding.getQualifiedName(), binding);
214 | }
215 | }
216 | @SuppressWarnings("unchecked")
217 | List superInterfaces = node.superInterfaceTypes();
218 | for (Type superInterface : superInterfaces)
219 | {
220 | ITypeBinding binding = superInterface.resolveBinding();
221 | String fqn = binding.getQualifiedName();
222 | if (binding != null && fqn.indexOf("java.") != 0 && fqn.indexOf("javax.") != 0)
223 | {
224 | parseSuper(fqn, binding);
225 | }
226 | }
227 | }
228 | nestLevel--;
229 | }
230 |
231 | private void parseSuper(String superclassFqn, ITypeBinding superclassBinding)
232 | {
233 | String superclassErasureFqn = superclassFqn;
234 | if (superclassBinding.isParameterizedType())
235 | {
236 | superclassErasureFqn = NameUtil.stripTypeArguments(superclassFqn);
237 | StringBuilder superclassFqnBuilder = new StringBuilder(superclassErasureFqn).append('<');
238 | List superclassTypeParams = NameUtil.extractTypeParams(superclassFqn);
239 | for (int i = 0; i < superclassTypeParams.size(); i++)
240 | {
241 | if (i > 0)
242 | superclassFqnBuilder.append(',');
243 | superclassFqnBuilder.append(
244 | NameUtil.resolveTypeParam(actualTypeParams, typeParams, superclassTypeParams.get(i)));
245 | }
246 | superclassFqnBuilder.append('>');
247 | superclassFqn = superclassFqnBuilder.toString();
248 | }
249 | Set subclasses = subclassMap.get(superclassErasureFqn);
250 | if (subclasses == null)
251 | {
252 | subclasses = Collections.newSetFromMap(new ConcurrentHashMap());
253 | subclassMap.put(superclassErasureFqn, subclasses);
254 | }
255 | subclasses.add(qualifiedName);
256 | BeanPropertyCache.parseBean(project, superclassFqn, readableFields, writableFields,
257 | subclassMap);
258 | }
259 |
260 | public static String getFieldNameFromAccessor(String methodName)
261 | {
262 | String fieldName = "";
263 | if (methodName != null)
264 | {
265 | if (methodName.startsWith("set") || methodName.startsWith("get"))
266 | {
267 | fieldName = Introspector.decapitalize(methodName.substring(3));
268 | }
269 | else if (methodName.startsWith("is"))
270 | {
271 | fieldName = Introspector.decapitalize(methodName.substring(2));
272 | }
273 | }
274 | return fieldName;
275 | }
276 | }
277 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/bean/JavaCompletionProposal.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.bean;
13 |
14 | import org.eclipse.core.runtime.Assert;
15 | import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
16 | import org.eclipse.jface.text.BadLocationException;
17 | import org.eclipse.jface.text.IDocument;
18 | import org.eclipse.jface.text.contentassist.IContextInformation;
19 | import org.eclipse.swt.graphics.Image;
20 | import org.eclipse.swt.graphics.Point;
21 |
22 | /**
23 | * @author Iwao AVE!
24 | */
25 | public class JavaCompletionProposal implements IJavaCompletionProposal
26 | {
27 |
28 | /** The string to be displayed in the completion proposal popup. */
29 | private String fDisplayString;
30 |
31 | /** The replacement string. */
32 | private String fReplacementString;
33 |
34 | /** The replacement offset. */
35 | private int fReplacementOffset;
36 |
37 | /** The replacement length. */
38 | private int fReplacementLength;
39 |
40 | /** The cursor position after this proposal has been applied. */
41 | private int fCursorPosition;
42 |
43 | /** The image to be displayed in the completion proposal popup. */
44 | private Image fImage;
45 |
46 | /** The context information of this proposal. */
47 | private IContextInformation fContextInformation;
48 |
49 | /** The additional info of this proposal. */
50 | private String fAdditionalProposalInfo;
51 |
52 | private int fRelevance;
53 |
54 | /**
55 | * Creates a new completion proposal based on the provided information. The replacement string
56 | * is considered being the display string too. All remaining fields are set to
57 | * null
.
58 | *
59 | * @param replacementString the actual string to be inserted into the document
60 | * @param replacementOffset the offset of the text to be replaced
61 | * @param replacementLength the length of the text to be replaced
62 | * @param cursorPosition the position of the cursor following the insert relative to
63 | * replacementOffset
64 | */
65 | public JavaCompletionProposal(
66 | String replacementString,
67 | int replacementOffset,
68 | int replacementLength,
69 | int cursorPosition,
70 | int relevance)
71 | {
72 | this(replacementString, replacementOffset, replacementLength, cursorPosition, null, null,
73 | null, null, relevance);
74 | }
75 |
76 | /**
77 | * Creates a new completion proposal. All fields are initialized based on the provided
78 | * information.
79 | *
80 | * @param replacementString the actual string to be inserted into the document
81 | * @param replacementOffset the offset of the text to be replaced
82 | * @param replacementLength the length of the text to be replaced
83 | * @param cursorPosition the position of the cursor following the insert relative to
84 | * replacementOffset
85 | * @param image the image to display for this proposal
86 | * @param displayString the string to be displayed for the proposal
87 | * @param contextInformation the context information associated with this proposal
88 | * @param additionalProposalInfo the additional information associated with this proposal
89 | */
90 | public JavaCompletionProposal(
91 | String replacementString,
92 | int replacementOffset,
93 | int replacementLength,
94 | int cursorPosition,
95 | Image image,
96 | String displayString,
97 | IContextInformation contextInformation,
98 | String additionalProposalInfo,
99 | int relevance)
100 | {
101 | Assert.isNotNull(replacementString);
102 | Assert.isTrue(replacementOffset >= 0);
103 | Assert.isTrue(replacementLength >= 0);
104 | Assert.isTrue(cursorPosition >= 0);
105 |
106 | fReplacementString = replacementString;
107 | fReplacementOffset = replacementOffset;
108 | fReplacementLength = replacementLength;
109 | fCursorPosition = cursorPosition;
110 | fImage = image;
111 | fDisplayString = displayString;
112 | fContextInformation = contextInformation;
113 | fAdditionalProposalInfo = additionalProposalInfo;
114 | fRelevance = relevance;
115 | }
116 |
117 | /*
118 | * @see ICompletionProposal#apply(IDocument)
119 | */
120 | public void apply(IDocument document)
121 | {
122 | try
123 | {
124 | document.replace(fReplacementOffset, fReplacementLength, fReplacementString);
125 | }
126 | catch (BadLocationException x)
127 | {
128 | // ignore
129 | }
130 | }
131 |
132 | /*
133 | * @see ICompletionProposal#getSelection(IDocument)
134 | */
135 | public Point getSelection(IDocument document)
136 | {
137 | return new Point(fReplacementOffset + fCursorPosition, 0);
138 | }
139 |
140 | /*
141 | * @see ICompletionProposal#getContextInformation()
142 | */
143 | public IContextInformation getContextInformation()
144 | {
145 | return fContextInformation;
146 | }
147 |
148 | /*
149 | * @see ICompletionProposal#getImage()
150 | */
151 | public Image getImage()
152 | {
153 | return fImage;
154 | }
155 |
156 | /*
157 | * @see ICompletionProposal#getDisplayString()
158 | */
159 | public String getDisplayString()
160 | {
161 | if (fDisplayString != null)
162 | return fDisplayString;
163 | return fReplacementString;
164 | }
165 |
166 | /*
167 | * @see ICompletionProposal#getAdditionalProposalInfo()
168 | */
169 | public String getAdditionalProposalInfo()
170 | {
171 | return fAdditionalProposalInfo;
172 | }
173 |
174 | public int getRelevance()
175 | {
176 | return fRelevance;
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/bean/SupertypeHierarchyCache.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.bean;
13 |
14 | import java.util.concurrent.ConcurrentHashMap;
15 |
16 | import org.eclipse.core.runtime.NullProgressMonitor;
17 | import org.eclipse.core.runtime.Status;
18 | import org.eclipse.jdt.core.IType;
19 | import org.eclipse.jdt.core.ITypeHierarchy;
20 | import org.eclipse.jdt.core.ITypeHierarchyChangedListener;
21 | import org.eclipse.jdt.core.JavaModelException;
22 |
23 | import net.harawata.mybatipse.Activator;
24 |
25 | /**
26 | * @author Iwao AVE!
27 | */
28 | public class SupertypeHierarchyCache
29 | {
30 | private static final SupertypeHierarchyCache INSTANCE = new SupertypeHierarchyCache();
31 |
32 | private final ConcurrentHashMap cache = new ConcurrentHashMap();
33 |
34 | public boolean isCollection(IType type)
35 | {
36 | return isSubtype(type, "java.util.Collection");
37 | }
38 |
39 | public boolean isList(IType type)
40 | {
41 | return isSubtype(type, "java.util.List");
42 | }
43 |
44 | public boolean isMap(IType type)
45 | {
46 | return isSubtype(type, "java.util.Map");
47 | }
48 |
49 | public boolean isSubtype(IType type, String supertypeFqn)
50 | {
51 | try
52 | {
53 | IType supertype = type.getJavaProject().findType(supertypeFqn);
54 | return isSubtype(type, supertype);
55 | }
56 | catch (JavaModelException e)
57 | {
58 | // This can be safely ignored.
59 | }
60 | return false;
61 | }
62 |
63 | public boolean isSubtype(IType type, IType supertype)
64 | {
65 | if (supertype == null)
66 | return false;
67 |
68 | try
69 | {
70 | ITypeHierarchy supertypes = getSupertypes(type);
71 | return supertypes.contains(supertype);
72 | }
73 | catch (JavaModelException e)
74 | {
75 | Activator.log(Status.ERROR, "Error while checking type hierarchy of "
76 | + type.getFullyQualifiedName() + " and " + supertype.getFullyQualifiedName(), e);
77 | }
78 | return false;
79 | }
80 |
81 | private ITypeHierarchy getSupertypes(final IType type) throws JavaModelException
82 | {
83 | ITypeHierarchy hierarchy = cache.get(type);
84 | if (hierarchy == null || !hierarchy.exists())
85 | {
86 | hierarchy = type.newSupertypeHierarchy(new NullProgressMonitor());
87 | hierarchy.addTypeHierarchyChangedListener(new ITypeHierarchyChangedListener()
88 | {
89 | @Override
90 | public void typeHierarchyChanged(ITypeHierarchy typeHierarchy)
91 | {
92 | cache.remove(type);
93 | }
94 | });
95 | cache.put(type, hierarchy);
96 | }
97 | return hierarchy;
98 | }
99 |
100 | public static SupertypeHierarchyCache getInstance()
101 | {
102 | return INSTANCE;
103 | }
104 |
105 | private SupertypeHierarchyCache()
106 | {
107 | super();
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/console/CopyLogStatementHandler.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.console;
13 |
14 | import org.eclipse.core.commands.AbstractHandler;
15 | import org.eclipse.core.commands.ExecutionEvent;
16 | import org.eclipse.core.commands.ExecutionException;
17 | import org.eclipse.jface.dialogs.MessageDialog;
18 | import org.eclipse.jface.text.TextSelection;
19 | import org.eclipse.jface.viewers.ISelection;
20 | import org.eclipse.swt.dnd.Clipboard;
21 | import org.eclipse.swt.dnd.TextTransfer;
22 | import org.eclipse.swt.dnd.Transfer;
23 | import org.eclipse.swt.widgets.Display;
24 | import org.eclipse.swt.widgets.Shell;
25 | import org.eclipse.ui.handlers.HandlerUtil;
26 |
27 | /**
28 | * @author Iwao AVE!
29 | */
30 | public class CopyLogStatementHandler extends AbstractHandler
31 | {
32 | @Override
33 | public Object execute(ExecutionEvent event) throws ExecutionException
34 | {
35 | ISelection selection = HandlerUtil.getCurrentSelection(event);
36 | if (selection instanceof TextSelection)
37 | {
38 | try
39 | {
40 | String statement = MybatisLogBinder.bind(((TextSelection)selection).getText());
41 | if (statement != null && statement.length() > 0)
42 | {
43 | Clipboard clipboard = new Clipboard(Display.getCurrent());
44 | clipboard.setContents(new Object[]{
45 | statement
46 | }, new Transfer[]{
47 | TextTransfer.getInstance()
48 | });
49 | }
50 | }
51 | catch (IllegalArgumentException e)
52 | {
53 | Shell shell = Display.getDefault().getActiveShell();
54 | MessageDialog.openInformation(shell, "Error", e.getMessage());
55 | }
56 | }
57 | return null;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/console/MybatisLogBinder.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.console;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Arrays;
16 | import java.util.List;
17 |
18 | /**
19 | * @author Iwao AVE!
20 | */
21 | public abstract class MybatisLogBinder
22 | {
23 | private static final String PREFIX_SQL = "==> Preparing:";
24 |
25 | private static final String PREFIX_PARAMS = "==> Parameters:";
26 |
27 | private static final String TERMINATOR = "<==";
28 |
29 | private static final List nonQuotedTypes = Arrays.asList("Integer", "Long", "Double",
30 | "Float", "Boolean");
31 |
32 | public static String bind(String src)
33 | {
34 | String statement = extractStatementLine(src);
35 | if (statement == null || statement.length() == 0)
36 | {
37 | return null;
38 | }
39 | String parametersLine = extractParametersLine(src);
40 | List params = extractParameters(parametersLine);
41 | if (params == null || params.size() == 0)
42 | {
43 | return statement;
44 | }
45 | else
46 | {
47 | // replace '?' with parameters.
48 | // it does not support statement contains non-placeholder question marks.
49 | StringBuilder sql = new StringBuilder();
50 | String[] segments = statement.split("\\?");
51 | for (int i = 0; i < segments.length; i++)
52 | {
53 | sql.append(segments[i]);
54 | if (i < params.size())
55 | {
56 | sql.append(params.get(i));
57 | }
58 | }
59 | return sql.toString();
60 | }
61 | }
62 |
63 | protected static String extractStatementLine(String src)
64 | {
65 | final int sqlPrefixStart = src.indexOf(PREFIX_SQL);
66 | if (sqlPrefixStart == -1)
67 | {
68 | throw new IllegalArgumentException(
69 | "Couldn't find the prefix of SQL statement line: '" + PREFIX_SQL + "'");
70 | }
71 | final int sqlStart = sqlPrefixStart + PREFIX_SQL.length();
72 | final int sqlEnd = src.indexOf('\n', sqlStart);
73 | if (sqlEnd == -1)
74 | {
75 | throw new IllegalArgumentException("Couldn't find the end of the SQL statement line.");
76 | }
77 | return src.substring(sqlStart, sqlEnd).trim();
78 | }
79 |
80 | protected static String extractParametersLine(String src)
81 | {
82 | int paramsPrefixStart = src.indexOf(PREFIX_PARAMS);
83 | if (paramsPrefixStart == -1)
84 | {
85 | throw new IllegalArgumentException(
86 | "Couldn't find the prefix of parameters line: '" + PREFIX_PARAMS + "'");
87 | }
88 | int paramsStart = paramsPrefixStart + PREFIX_SQL.length();
89 | // Nested selects.
90 | int nextSqlStartPos = src.indexOf(PREFIX_SQL, paramsStart);
91 | int terminatorPos = src.indexOf(TERMINATOR, paramsStart);
92 | if (nextSqlStartPos > -1 && (nextSqlStartPos < terminatorPos || terminatorPos == -1))
93 | {
94 | terminatorPos = nextSqlStartPos;
95 | }
96 | else if (terminatorPos == -1)
97 | {
98 | throw new IllegalArgumentException(
99 | "Failed to parse the parameters. Be sure to include the string '" + TERMINATOR
100 | + "' in the selection.");
101 | }
102 | int paramsEnd = src.lastIndexOf('\n', terminatorPos);
103 | return src.substring(paramsStart, paramsEnd).trim();
104 | }
105 |
106 | protected static List extractParameters(String src)
107 | {
108 | if (src == null || src.length() == 0)
109 | {
110 | return null;
111 | }
112 | // it does not work if a string parameter contains '), ' as literal.
113 | List params = new ArrayList();
114 | int cursor = src.length();
115 | while (cursor > -1)
116 | {
117 | if (src.lastIndexOf("null", cursor) == cursor - 4)
118 | {
119 | params.add(0, "null");
120 | cursor = src.lastIndexOf("null", cursor) - 2;
121 | }
122 | else if (src.charAt(cursor - 1) == ')')
123 | {
124 | int typeStart = src.lastIndexOf('(', cursor);
125 | String type = src.substring(typeStart + 1, cursor - 1);
126 |
127 | cursor = typeStart;
128 | int valueStart = src.lastIndexOf(", ", cursor);
129 | while (valueStart > -1 && src.lastIndexOf("null", valueStart) != valueStart - 4
130 | && src.charAt(valueStart - 1) != ')')
131 | {
132 | valueStart = src.lastIndexOf(", ", valueStart - 1);
133 | }
134 | String value = src.substring(valueStart == -1 ? 0 : valueStart + 2, cursor);
135 | cursor = valueStart;
136 | if (nonQuotedTypes.contains(type))
137 | {
138 | params.add(0, value);
139 | }
140 | else
141 | {
142 | params.add(0, "'" + value + "'");
143 | }
144 | }
145 | else
146 | {
147 | cursor = -1;
148 | }
149 | }
150 | return params;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/hyperlink/HyperlinkDetector.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.hyperlink;
13 |
14 | import java.text.MessageFormat;
15 |
16 | import org.eclipse.jdt.core.IField;
17 | import org.eclipse.jdt.core.IJavaProject;
18 | import org.eclipse.jdt.core.IType;
19 | import org.eclipse.jdt.core.JavaModelException;
20 | import org.eclipse.jface.text.IRegion;
21 | import org.eclipse.jface.text.Region;
22 | import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
23 | import org.eclipse.jface.text.hyperlink.IHyperlink;
24 |
25 | import net.harawata.mybatipse.mybatis.JavaMapperUtil;
26 | import net.harawata.mybatipse.mybatis.JavaMapperUtil.MethodMatcher;
27 | import net.harawata.mybatipse.mybatis.JavaMapperUtil.SingleMethodStore;
28 | import net.harawata.mybatipse.mybatis.MybatipseXmlUtil;
29 | import net.harawata.mybatipse.mybatis.TypeAliasCache;
30 |
31 | /**
32 | * @author Iwao AVE!
33 | */
34 | public abstract class HyperlinkDetector extends AbstractHyperlinkDetector
35 | {
36 | protected IHyperlink linkToJavaMapperMethod(IJavaProject project, String mapperFqn,
37 | IRegion linkRegion, MethodMatcher methodMatcher)
38 | {
39 | SingleMethodStore methodStore = new SingleMethodStore();
40 | JavaMapperUtil.findMapperMethod(methodStore, project, mapperFqn, methodMatcher);
41 | if (methodStore.isEmpty())
42 | return null;
43 | return new ToJavaHyperlink(methodStore.getMethod(), linkRegion, "Open mapper method.");
44 | }
45 |
46 | protected IHyperlink linkToJavaProperty(IJavaProject project, String qualifiedName,
47 | String propertyName, Region linkRegion) throws JavaModelException
48 | {
49 | // Ignore default type aliases.
50 | if (MybatipseXmlUtil.isDefaultTypeAlias(qualifiedName))
51 | return null;
52 |
53 | IType javaType = project.findType(qualifiedName);
54 | if (javaType == null)
55 | {
56 | String resolvedAlias = TypeAliasCache.getInstance()
57 | .resolveAlias(project, qualifiedName, null);
58 | if (resolvedAlias != null)
59 | {
60 | javaType = project.findType(resolvedAlias);
61 | }
62 | }
63 | if (javaType != null)
64 | {
65 | // TODO: should search setter first?
66 | // TODO: field of super type, nested property
67 | IField field = javaType.getField(propertyName);
68 | if (field != null)
69 | {
70 | return new ToJavaHyperlink(field, linkRegion, javaLinkLabel("property"));
71 | }
72 | }
73 | return null;
74 | }
75 |
76 | protected String javaLinkLabel(String target)
77 | {
78 | return MessageFormat.format("Open {0} in Java Editor", target);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/hyperlink/ToJavaHyperlink.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.hyperlink;
13 |
14 | import org.eclipse.core.runtime.Status;
15 | import org.eclipse.jdt.core.IJavaElement;
16 | import org.eclipse.jdt.ui.JavaUI;
17 | import org.eclipse.jface.text.IRegion;
18 | import org.eclipse.jface.text.hyperlink.IHyperlink;
19 |
20 | import net.harawata.mybatipse.Activator;
21 |
22 | /**
23 | * @author Iwao AVE!
24 | */
25 | public class ToJavaHyperlink implements IHyperlink
26 | {
27 | private IJavaElement type;
28 |
29 | private IRegion region;
30 |
31 | private String linkLabel;
32 |
33 | public ToJavaHyperlink(IJavaElement type, IRegion region, String linkLabel)
34 | {
35 | super();
36 | this.type = type;
37 | this.region = region;
38 | this.linkLabel = linkLabel;
39 | }
40 |
41 | public IRegion getHyperlinkRegion()
42 | {
43 | return region;
44 | }
45 |
46 | public String getTypeLabel()
47 | {
48 | return linkLabel;
49 | }
50 |
51 | public String getHyperlinkText()
52 | {
53 | return linkLabel;
54 | }
55 |
56 | public void open()
57 | {
58 | try
59 | {
60 | JavaUI.openInEditor(type);
61 | }
62 | catch (Exception e)
63 | {
64 | Activator.log(Status.WARNING,
65 | "Failed to open Java editor for type: " + type.getElementName(), e);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/hyperlink/ToXmlHyperlink.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.hyperlink;
13 |
14 | import org.eclipse.core.resources.IFile;
15 | import org.eclipse.core.runtime.Status;
16 | import org.eclipse.jface.text.IRegion;
17 | import org.eclipse.jface.text.ITextViewer;
18 | import org.eclipse.jface.text.hyperlink.IHyperlink;
19 | import org.eclipse.ui.IEditorPart;
20 | import org.eclipse.ui.IWorkbenchWindow;
21 | import org.eclipse.ui.PlatformUI;
22 | import org.eclipse.ui.ide.IDE;
23 | import org.eclipse.ui.part.MultiPageEditorPart;
24 | import org.eclipse.ui.texteditor.ITextEditor;
25 |
26 | import net.harawata.mybatipse.Activator;
27 |
28 | /**
29 | * @author Iwao AVE!
30 | */
31 | public class ToXmlHyperlink implements IHyperlink
32 | {
33 | private ITextViewer textViewer;
34 |
35 | private IFile file;
36 |
37 | private IRegion srcRegion;
38 |
39 | private String linkLabel;
40 |
41 | private IRegion destRegion;
42 |
43 | public ToXmlHyperlink(
44 | ITextViewer textViewer,
45 | IRegion srcRegion,
46 | String linkLabel,
47 | IRegion destRegion)
48 | {
49 | super();
50 | this.textViewer = textViewer;
51 | this.srcRegion = srcRegion;
52 | this.linkLabel = linkLabel;
53 | this.destRegion = destRegion;
54 | }
55 |
56 | public ToXmlHyperlink(IFile file, IRegion srcRegion, String linkLabel, IRegion destRegion)
57 | {
58 | this.file = file;
59 | this.srcRegion = srcRegion;
60 | this.linkLabel = linkLabel;
61 | this.destRegion = destRegion;
62 | }
63 |
64 | public IRegion getHyperlinkRegion()
65 | {
66 | return srcRegion;
67 | }
68 |
69 | public String getTypeLabel()
70 | {
71 | return linkLabel;
72 | }
73 |
74 | public String getHyperlinkText()
75 | {
76 | return linkLabel;
77 | }
78 |
79 | public void open()
80 | {
81 | if (file == null)
82 | {
83 | textViewer.setSelectedRange(destRegion.getOffset(), destRegion.getLength());
84 | textViewer.revealRange(destRegion.getOffset(), destRegion.getLength());
85 | }
86 | else
87 | {
88 | try
89 | {
90 | IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
91 | if (window != null)
92 | {
93 | IEditorPart editorPart = IDE.openEditor(window.getActivePage(), file);
94 | if (editorPart instanceof MultiPageEditorPart)
95 | {
96 | MultiPageEditorPart multiPageEditorPart = (MultiPageEditorPart)editorPart;
97 | IEditorPart[] editors = multiPageEditorPart
98 | .findEditors(editorPart.getEditorInput());
99 | if (editors.length == 1 && editors[0] instanceof ITextEditor)
100 | {
101 | ((ITextEditor)editors[0]).selectAndReveal(destRegion.getOffset(),
102 | destRegion.getLength());
103 | }
104 | }
105 | }
106 | }
107 | catch (Exception e)
108 | {
109 | Activator.log(Status.WARNING, e.getMessage(), e);
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/mybatis/ConfigRegistry.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.mybatis;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import java.util.Map;
17 | import java.util.concurrent.ConcurrentHashMap;
18 |
19 | import org.eclipse.core.resources.IContainer;
20 | import org.eclipse.core.resources.IFile;
21 | import org.eclipse.core.resources.IProject;
22 | import org.eclipse.core.resources.IResource;
23 | import org.eclipse.core.resources.IResourceProxy;
24 | import org.eclipse.core.resources.IResourceProxyVisitor;
25 | import org.eclipse.core.runtime.CoreException;
26 | import org.eclipse.core.runtime.Status;
27 | import org.eclipse.core.runtime.content.IContentDescription;
28 | import org.eclipse.core.runtime.content.IContentType;
29 | import org.eclipse.jdt.core.IJavaProject;
30 | import org.eclipse.jdt.core.IPackageFragmentRoot;
31 |
32 | import net.harawata.mybatipse.Activator;
33 |
34 | /**
35 | * @author Iwao AVE!
36 | */
37 | public class ConfigRegistry
38 | {
39 | private static final ConfigRegistry INSTANCE = new ConfigRegistry();
40 |
41 | private Map> configMap = new ConcurrentHashMap>();
42 |
43 | // public void put(IProject project, IFile configFile)
44 | // {
45 | // configMap.put(project.getName(), configFile);
46 | // TypeAliasCache.getInstance().remove(project);
47 | // }
48 |
49 | public Map get(IJavaProject javaProject)
50 | {
51 | IProject project = javaProject.getProject();
52 | Map files = configMap.get(project.getName());
53 | if (files == null)
54 | {
55 | files = search(javaProject);
56 | configMap.put(project.getName(), files);
57 | TypeAliasCache.getInstance().remove(project);
58 | }
59 | return files;
60 | }
61 |
62 | public void clear()
63 | {
64 | configMap.clear();
65 | TypeAliasCache.getInstance().clear();
66 | }
67 |
68 | public void remove(IProject project)
69 | {
70 | configMap.remove(project.getName());
71 | TypeAliasCache.getInstance().remove(project);
72 | }
73 |
74 | public void remove(IProject project, IFile file)
75 | {
76 | Map files = configMap.get(project.getName());
77 | if (files != null)
78 | files.remove(file);
79 | TypeAliasCache.getInstance().remove(project);
80 | }
81 |
82 | /**
83 | * Scans the project and returns the MyBatis config file if found.
84 | * If there are multiple files in the project, only the first one is returned.
85 | *
86 | * @param project
87 | * @return MyBatis config file or null
if none found.
88 | */
89 | private Map search(IJavaProject project)
90 | {
91 | final Map configFiles = new ConcurrentHashMap();
92 | try
93 | {
94 | project.getResource().accept(new ConfigVisitor(configFiles), IContainer.NONE);
95 |
96 | for (IPackageFragmentRoot root : project.getPackageFragmentRoots())
97 | {
98 | if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
99 | continue;
100 | root.getResource().accept(new ConfigVisitor(configFiles), IContainer.NONE);
101 | }
102 | }
103 | catch (CoreException e)
104 | {
105 | Activator.log(Status.ERROR, "Searching MyBatis Config xml failed.", e);
106 | }
107 |
108 | return configFiles;
109 | }
110 |
111 | public static ConfigRegistry getInstance()
112 | {
113 | return INSTANCE;
114 | }
115 |
116 | private ConfigRegistry()
117 | {
118 | super();
119 | }
120 |
121 | private class ConfigVisitor implements IResourceProxyVisitor
122 | {
123 | private final Map configFiles;
124 |
125 | private ConfigVisitor(Map configFiles)
126 | {
127 | this.configFiles = configFiles;
128 | }
129 |
130 | @Override
131 | public boolean visit(IResourceProxy proxy) throws CoreException
132 | {
133 | if (proxy.isDerived())
134 | return false;
135 |
136 | if (proxy.getType() == IResource.FILE && proxy.getName().endsWith(".xml"))
137 | {
138 | IFile file = (IFile)proxy.requestResource();
139 | IContentDescription contentDesc = file.getContentDescription();
140 | if (contentDesc != null)
141 | {
142 | IContentType contentType = contentDesc.getContentType();
143 | if (contentType != null && (contentType.isKindOf(configContentType)
144 | || contentType.isKindOf(springConfigContentType)))
145 | {
146 | configFiles.put(file, contentType);
147 | }
148 | }
149 | }
150 | return true;
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/mybatis/ExpressionProposalParser.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.mybatis;
13 |
14 | /**
15 | * @author Iwao AVE!
16 | */
17 | public class ExpressionProposalParser
18 | {
19 | private final String text;
20 |
21 | private final int offset;
22 |
23 | private String matchString;
24 |
25 | private String proposalTarget;
26 |
27 | private boolean proposable;
28 |
29 | public ExpressionProposalParser(String text, int offset)
30 | {
31 | this.text = text;
32 | this.offset = offset;
33 | parse();
34 | }
35 |
36 | private void parse()
37 | {
38 | StringBuilder buffer = new StringBuilder();
39 | int trailingWhitespaceMode = 0;
40 | for (int i = offset; i > 0; i--)
41 | {
42 | char c = text.charAt(i);
43 | if (c <= 0x20)
44 | {
45 | if (trailingWhitespaceMode == 0)
46 | trailingWhitespaceMode = 1;
47 | }
48 | else if (Character.isJavaIdentifierPart(c) || c == '[' || c == ']' || c == '.')
49 | {
50 | if (trailingWhitespaceMode == 1)
51 | break;
52 | buffer.insert(0, c);
53 | }
54 | else if (c == ',')
55 | {
56 | trailingWhitespaceMode = 2;
57 | if (matchString == null)
58 | {
59 | matchString = buffer.toString();
60 | buffer.setLength(0);
61 | }
62 | if (proposalTarget == null)
63 | {
64 | proposalTarget = buffer.toString();
65 | buffer.setLength(0);
66 | }
67 | }
68 | else if (c == '=')
69 | {
70 | trailingWhitespaceMode = 2;
71 | if (matchString == null)
72 | {
73 | matchString = buffer.toString();
74 | }
75 | buffer.setLength(0);
76 | }
77 | else if (c == '{' && i > 0)
78 | {
79 | char preChr = text.charAt(i - 1);
80 | if (preChr == '#' || preChr == '$')
81 | {
82 | proposable = true;
83 | if (matchString == null)
84 | {
85 | proposalTarget = "property";
86 | matchString = buffer.toString();
87 | }
88 | else if (preChr == '$')
89 | {
90 | proposable = false;
91 | }
92 | break;
93 | }
94 | }
95 | else
96 | {
97 | break;
98 | }
99 | }
100 | }
101 |
102 | public int getReplacementLength()
103 | {
104 | boolean inWhitespace = false;
105 | int i = offset + 1;
106 | for (; i < text.length(); i++)
107 | {
108 | char c = text.charAt(i);
109 | if (Character.isJavaIdentifierPart(c) || c == '[' || c == ']' || c == '.')
110 | {
111 | if (inWhitespace)
112 | return i - offset - 1 + matchString.length();
113 | }
114 | else if (c <= 0x20)
115 | {
116 | if (c == 0x0A || c == 0x0D)
117 | return i - offset - 1 + matchString.length();
118 | inWhitespace = true;
119 | }
120 | else
121 | {
122 | break;
123 | }
124 | }
125 | return i - offset - 1 + matchString.length();
126 | }
127 |
128 | public String getMatchString()
129 | {
130 | return matchString;
131 | }
132 |
133 | public String getProposalTarget()
134 | {
135 | return proposalTarget;
136 | }
137 |
138 | public boolean isProposable()
139 | {
140 | return proposable;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/mybatis/MapperNamespaceCache.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.mybatis;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import java.util.Collections;
17 | import java.util.HashSet;
18 | import java.util.Iterator;
19 | import java.util.Map;
20 | import java.util.Set;
21 | import java.util.concurrent.ConcurrentHashMap;
22 |
23 | import org.eclipse.core.resources.IContainer;
24 | import org.eclipse.core.resources.IFile;
25 | import org.eclipse.core.resources.IProject;
26 | import org.eclipse.core.resources.IResource;
27 | import org.eclipse.core.resources.IResourceProxy;
28 | import org.eclipse.core.resources.IResourceProxyVisitor;
29 | import org.eclipse.core.runtime.CoreException;
30 | import org.eclipse.core.runtime.Platform;
31 | import org.eclipse.core.runtime.Status;
32 | import org.eclipse.core.runtime.content.IContentDescription;
33 | import org.eclipse.core.runtime.content.IContentType;
34 | import org.eclipse.jdt.core.IJavaProject;
35 | import org.eclipse.jdt.core.IPackageFragmentRoot;
36 | import org.eclipse.wst.sse.core.StructuredModelManager;
37 | import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
38 | import org.eclipse.wst.validation.internal.provisional.core.IReporter;
39 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
40 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
41 | import org.w3c.dom.Node;
42 |
43 | import net.harawata.mybatipse.Activator;
44 | import net.harawata.mybatipse.util.XpathUtil;
45 |
46 | /**
47 | * @author Iwao AVE!
48 | */
49 | @SuppressWarnings("restriction")
50 | public class MapperNamespaceCache
51 | {
52 | private static final MapperNamespaceCache INSTANCE = new MapperNamespaceCache();
53 |
54 | private IContentType mapperContentType = Platform.getContentTypeManager()
55 | .getContentType(CONTENT_TYPE_MAPPER);
56 |
57 | private final Map>> cache = new ConcurrentHashMap>>();
58 |
59 | public Set get(IJavaProject javaProject, String namespace, IReporter reporter)
60 | {
61 | Map> map = getCacheMap(javaProject, reporter);
62 | Set xmlMapperFiles = map.get(namespace);
63 | return xmlMapperFiles == null ? Collections. emptySet() : xmlMapperFiles;
64 | }
65 |
66 | public void clear()
67 | {
68 | cache.clear();
69 | }
70 |
71 | public void remove(IProject project)
72 | {
73 | cache.remove(project.getName());
74 | }
75 |
76 | public void remove(String projectName, IFile file)
77 | {
78 | String namespace = extractNamespace(file);
79 | remove(projectName, namespace, file);
80 | }
81 |
82 | protected void remove(String projectName, String namespace, IFile file)
83 | {
84 | Map> map = cache.get(projectName);
85 | if (map == null)
86 | return;
87 | Set files = map.get(namespace);
88 | if (files == null)
89 | return;
90 | Iterator iterator = files.iterator();
91 | while (iterator.hasNext())
92 | {
93 | IFile cachedFile = iterator.next();
94 | if (cachedFile.getFullPath().equals(file.getFullPath()))
95 | {
96 | iterator.remove();
97 | }
98 | }
99 | }
100 |
101 | public void put(String projectName, IFile file)
102 | {
103 | Map> map = cache.get(projectName);
104 | if (map == null)
105 | return;
106 |
107 | String namespace = extractNamespace(file);
108 | if (namespace != null)
109 | {
110 | remove(projectName, namespace, file);
111 | Set set = map.get(namespace);
112 | if (set == null)
113 | {
114 | set = new HashSet<>();
115 | map.put(namespace, set);
116 | }
117 | set.add(file);
118 | }
119 | }
120 |
121 | public Map> getCacheMap(IJavaProject javaProject, IReporter reporter)
122 | {
123 | String projectName = javaProject.getElementName();
124 | Map> map = cache.get(projectName);
125 | if (map == null)
126 | {
127 | map = new ConcurrentHashMap>();
128 | cache.put(projectName, map);
129 | collectMappers(javaProject, map, reporter);
130 | }
131 | return map;
132 | }
133 |
134 | private void collectMappers(IJavaProject project, final Map> map,
135 | final IReporter reporter)
136 | {
137 | try
138 | {
139 | for (IPackageFragmentRoot root : project.getAllPackageFragmentRoots())
140 | {
141 | if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
142 | {
143 | continue;
144 | }
145 |
146 | root.getResource().accept(new IResourceProxyVisitor()
147 | {
148 | @Override
149 | public boolean visit(IResourceProxy proxy) throws CoreException
150 | {
151 | if (!proxy.isDerived() && proxy.getType() == IResource.FILE
152 | && proxy.getName().endsWith(".xml"))
153 | {
154 | IFile file = (IFile)proxy.requestResource();
155 | IContentDescription contentDesc = file.getContentDescription();
156 | if (contentDesc != null)
157 | {
158 | IContentType contentType = contentDesc.getContentType();
159 | if (contentType != null && contentType.isKindOf(mapperContentType))
160 | {
161 | String namespace = extractNamespace(file);
162 | if (namespace != null)
163 | {
164 | Set set = map.get(namespace);
165 | if (set == null)
166 | {
167 | set = new HashSet<>();
168 | map.put(namespace, set);
169 | }
170 | set.add(file);
171 | }
172 | return false;
173 | }
174 | }
175 | }
176 | return true;
177 | }
178 | }, IContainer.NONE);
179 | }
180 | }
181 | catch (CoreException e)
182 | {
183 | Activator.log(Status.ERROR, "Searching MyBatis Mapper xml failed.", e);
184 | }
185 | }
186 |
187 | private String extractNamespace(IFile file)
188 | {
189 | IStructuredModel model = null;
190 | try
191 | {
192 | model = StructuredModelManager.getModelManager().getModelForRead(file);
193 | IDOMModel domModel = (IDOMModel)model;
194 | IDOMDocument domDoc = domModel.getDocument();
195 |
196 | Node node = XpathUtil.xpathNode(domDoc, "//mapper/@namespace");
197 | return node == null ? null : node.getNodeValue();
198 | }
199 | catch (Exception e)
200 | {
201 | Activator.log(Status.ERROR, "Error occurred during parsing mapper:" + file.getFullPath(),
202 | e);
203 | }
204 | finally
205 | {
206 | if (model != null)
207 | {
208 | model.releaseFromRead();
209 | }
210 | }
211 | return null;
212 | }
213 |
214 | public static MapperNamespaceCache getInstance()
215 | {
216 | return INSTANCE;
217 | }
218 |
219 | private MapperNamespaceCache()
220 | {
221 | super();
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/mybatis/MybatipseXmlUtil.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.mybatis;
13 |
14 | import java.util.Arrays;
15 | import java.util.HashSet;
16 | import java.util.List;
17 | import java.util.Locale;
18 | import java.util.Set;
19 |
20 | import javax.xml.xpath.XPathExpressionException;
21 |
22 | import org.eclipse.core.resources.IFile;
23 | import org.eclipse.core.resources.IProject;
24 | import org.eclipse.core.resources.IWorkspaceRoot;
25 | import org.eclipse.core.resources.ResourcesPlugin;
26 | import org.eclipse.core.runtime.IPath;
27 | import org.eclipse.core.runtime.Path;
28 | import org.eclipse.core.runtime.Status;
29 | import org.eclipse.jdt.core.IClasspathEntry;
30 | import org.eclipse.jdt.core.IJavaProject;
31 | import org.eclipse.jdt.core.JavaCore;
32 | import org.eclipse.jdt.core.JavaModelException;
33 | import org.eclipse.jface.text.IDocument;
34 | import org.eclipse.ui.IEditorInput;
35 | import org.eclipse.ui.IEditorPart;
36 | import org.eclipse.ui.IWorkbench;
37 | import org.eclipse.ui.IWorkbenchPage;
38 | import org.eclipse.ui.IWorkbenchWindow;
39 | import org.eclipse.ui.PlatformUI;
40 | import org.eclipse.ui.part.FileEditorInput;
41 | import org.eclipse.wst.sse.core.StructuredModelManager;
42 | import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
43 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
44 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
45 | import org.w3c.dom.Document;
46 | import org.w3c.dom.NamedNodeMap;
47 | import org.w3c.dom.Node;
48 |
49 | import net.harawata.mybatipse.Activator;
50 | import net.harawata.mybatipse.util.XpathUtil;
51 |
52 | /**
53 | * @author Iwao AVE!
54 | */
55 | @SuppressWarnings("restriction")
56 | public class MybatipseXmlUtil
57 | {
58 | private static final List defaultTypeAliases = Arrays.asList("string", "map",
59 | "hashmap", "list", "arraylist", "collection", "iterator", "resultset",
60 |
61 | "_byte", "_long", "_short", "_int", "_integer", "_double", "_float", "_boolean",
62 |
63 | "_byte[]", "_long[]", "_short[]", "_int[]", "_integer[]", "_double[]", "_float[]",
64 | "_boolean[]",
65 |
66 | "byte", "long", "short", "int", "integer", "double", "float", "boolean",
67 |
68 | "byte[]", "long[]", "short[]", "int[]", "integer[]", "double[]", "float[]", "boolean[]",
69 |
70 | "date", "decimal", "bigdecimal", "biginteger", "object",
71 |
72 | "date[]", "decimal[]", "bigdecimal[]", "biginteger[]", "object[]",
73 |
74 | "jdbc", "managed",
75 |
76 | "jndi", "pooled", "unpooled",
77 |
78 | "perpetual", "fifo", "lru", "soft", "weak",
79 |
80 | "db_vendor",
81 |
82 | "xml", "raw",
83 |
84 | "slf4j", "commons_logging", "log4j", "log4j2", "jdk_logging", "stdout_logging",
85 | "no_logging",
86 |
87 | "cglib", "javassist");
88 |
89 | public static boolean isDefaultTypeAlias(String type)
90 | {
91 | return type != null && defaultTypeAliases.contains(type.toLowerCase(Locale.ENGLISH));
92 | }
93 |
94 | public static IJavaProject getJavaProject(IDocument document)
95 | {
96 | IStructuredModel model = null;
97 | String baseLocation = null;
98 | IJavaProject result = null;
99 |
100 | // try to locate the file in the workspace
101 | try
102 | {
103 | model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
104 | if (model != null)
105 | {
106 | baseLocation = model.getBaseLocation();
107 | }
108 | }
109 | finally
110 | {
111 | if (model != null)
112 | model.releaseFromRead();
113 | }
114 | if (baseLocation != null)
115 | {
116 | IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
117 | IPath filePath = new Path(baseLocation);
118 | IFile file = null;
119 |
120 | if (filePath.segmentCount() > 1)
121 | {
122 | file = root.getFile(filePath);
123 | }
124 | if (file != null)
125 | {
126 | IProject project = file.getProject();
127 | result = JavaCore.create(project);
128 | }
129 | }
130 | return result;
131 | }
132 |
133 | public static String getNamespace(Document document)
134 | {
135 | try
136 | {
137 | return XpathUtil.xpathString(document, "//mapper/@namespace");
138 | }
139 | catch (XPathExpressionException e)
140 | {
141 | Activator.log(Status.ERROR, "Invalid xpath (unexpected)", e);
142 | }
143 | return null;
144 | }
145 |
146 | public static String getNamespaceFromActiveEditor(IJavaProject project)
147 | {
148 | IWorkbench wb = PlatformUI.getWorkbench();
149 | IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
150 | IWorkbenchPage page = window.getActivePage();
151 | IEditorPart editor = page.getActiveEditor();
152 | IEditorInput input = editor.getEditorInput();
153 | IPath path = ((FileEditorInput)input).getFile().getFullPath();
154 |
155 | try
156 | {
157 | for (IClasspathEntry entry : project.getRawClasspath())
158 | {
159 | if (entry.getPath().isPrefixOf(path))
160 | {
161 | IPath relativePath = path.makeRelativeTo(entry.getPath());
162 | return relativePath.removeFileExtension().toString().replace('/', '.');
163 | }
164 | }
165 | }
166 | catch (JavaModelException e)
167 | {
168 | Activator.log(Status.ERROR,
169 | "Failed to get raw classpath for project: " + project.getElementName(), e);
170 | }
171 | return null;
172 | }
173 |
174 | public static Set getMapperDocument(IJavaProject project, String namespace)
175 | {
176 | Set results = new HashSet<>();
177 | for (IFile mapperFile : MapperNamespaceCache.getInstance().get(project, namespace, null))
178 | {
179 | results.add(MybatipseXmlUtil.getMapperDocument(mapperFile));
180 | }
181 | return results;
182 | }
183 |
184 | public static IDOMDocument getMapperDocument(IFile mapperXmlFile)
185 | {
186 | if (mapperXmlFile == null)
187 | return null;
188 | IStructuredModel model = null;
189 | try
190 | {
191 | model = StructuredModelManager.getModelManager().getModelForRead(mapperXmlFile);
192 | if (model == null)
193 | return null;
194 | IDOMModel domModel = (IDOMModel)model;
195 | IDOMDocument mapperDocument = domModel.getDocument();
196 | return mapperDocument;
197 | }
198 | catch (Exception e)
199 | {
200 | Activator.log(Status.ERROR, e.getMessage(), e);
201 | }
202 | finally
203 | {
204 | if (model != null)
205 | {
206 | model.releaseFromRead();
207 | }
208 | }
209 | return null;
210 | }
211 |
212 | public static Node findEnclosingStatementNode(Node parentNode)
213 | {
214 | try
215 | {
216 | return XpathUtil.xpathNode(parentNode, "ancestor-or-self::select|ancestor-or-self::update"
217 | + "|ancestor-or-self::insert|ancestor-or-self::delete");
218 | }
219 | catch (XPathExpressionException e)
220 | {
221 | Activator.log(Status.ERROR, e.getMessage(), e);
222 | }
223 | return null;
224 | }
225 |
226 | public static String findEnclosingType(Node node)
227 | {
228 | String type = null;
229 | Node parentNode = node.getParentNode();
230 | while (parentNode != null && type == null)
231 | {
232 | String nodeName = parentNode.getNodeName();
233 | if ("resultMap".equals(nodeName))
234 | type = getAttribute(parentNode, "type");
235 | else if ("collection".equals(nodeName))
236 | type = getAttribute(parentNode, "ofType");
237 | else if ("association".equals(nodeName))
238 | type = getAttribute(parentNode, "javaType");
239 | else if ("case".equals(nodeName))
240 | type = getAttribute(parentNode, "resultType");
241 | parentNode = parentNode.getParentNode();
242 | }
243 | return normalizeTypeName(type);
244 | }
245 |
246 | public static String normalizeTypeName(String src)
247 | {
248 | return src == null ? null : src.replace('$', '.');
249 | }
250 |
251 | private static String getAttribute(Node node, String attributeName)
252 | {
253 | NamedNodeMap attributes = node.getAttributes();
254 | if (attributes != null)
255 | {
256 | Node typeAttrNode = attributes.getNamedItem(attributeName);
257 | if (typeAttrNode != null)
258 | {
259 | return typeAttrNode.getNodeValue();
260 | }
261 | }
262 | return null;
263 | }
264 |
265 | private MybatipseXmlUtil()
266 | {
267 | }
268 | }
269 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/mybatis/TypeAliasMap.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.mybatis;
13 |
14 | import java.util.Locale;
15 | import java.util.concurrent.ConcurrentHashMap;
16 |
17 | import net.harawata.mybatipse.mybatis.TypeAliasMap.TypeAliasInfo;
18 |
19 | /**
20 | * @author Iwao AVE!
21 | */
22 | public class TypeAliasMap extends ConcurrentHashMap
23 | {
24 | private static final long serialVersionUID = -7286252877431348258L;
25 |
26 | public void put(String qualifiedName)
27 | {
28 | put(null, qualifiedName);
29 | }
30 |
31 | public void put(String alias, String qualifiedName)
32 | {
33 | if (qualifiedName == null || qualifiedName.length() == 0)
34 | return;
35 |
36 | if (alias == null || alias.length() == 0)
37 | {
38 | int lastDot = qualifiedName.lastIndexOf('.');
39 | alias = lastDot == -1 ? qualifiedName : qualifiedName.substring(lastDot + 1);
40 | }
41 |
42 | this.put(alias.toLowerCase(Locale.ENGLISH), new TypeAliasInfo(alias, qualifiedName));
43 | }
44 |
45 | static class TypeAliasInfo
46 | {
47 | private String aliasToInsert;
48 |
49 | private String qualifiedName;
50 |
51 | public String getAliasToInsert()
52 | {
53 | return aliasToInsert;
54 | }
55 |
56 | public void setAliasToInsert(String aliasToInsert)
57 | {
58 | this.aliasToInsert = aliasToInsert;
59 | }
60 |
61 | public String getQualifiedName()
62 | {
63 | return qualifiedName;
64 | }
65 |
66 | public void setQualifiedName(String qualifiedName)
67 | {
68 | this.qualifiedName = qualifiedName;
69 | }
70 |
71 | private TypeAliasInfo(String aliasToInsert, String qualifiedName)
72 | {
73 | super();
74 | this.aliasToInsert = aliasToInsert;
75 | this.qualifiedName = qualifiedName;
76 | }
77 |
78 | @Override
79 | public String toString()
80 | {
81 | return "[" + aliasToInsert + " : " + qualifiedName + "]";
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/mybatis/ValidatorHelper.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.mybatis;
13 |
14 | import java.util.Set;
15 |
16 | import javax.xml.xpath.XPathExpressionException;
17 |
18 | import org.eclipse.core.runtime.Status;
19 | import org.eclipse.jdt.core.IJavaProject;
20 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
21 |
22 | import net.harawata.mybatipse.Activator;
23 | import net.harawata.mybatipse.cache.JavaMapperCache;
24 | import net.harawata.mybatipse.util.XpathUtil;
25 |
26 | /**
27 | * @author Iwao AVE!
28 | */
29 | @SuppressWarnings("restriction")
30 | public class ValidatorHelper
31 | {
32 | public static boolean isReferenceValid(IJavaProject project, String localNamespace,
33 | String reference, String targetElement)
34 | {
35 | try
36 | {
37 | if (reference.indexOf("${") > -1)
38 | return true;
39 |
40 | final String namespace;
41 | final String id;
42 |
43 | if (reference.indexOf('.') == -1)
44 | {
45 | // Local reference
46 | id = reference;
47 | namespace = localNamespace;
48 | }
49 | else
50 | {
51 | // External reference
52 | int lastDot = reference.lastIndexOf('.');
53 | namespace = reference.substring(0, lastDot);
54 | id = reference.substring(lastDot + 1);
55 | }
56 |
57 | // Check Java mapper
58 | if ("select".equals(targetElement))
59 | {
60 | if (JavaMapperCache.getInstance().selectMethodExists(project, namespace, id))
61 | {
62 | return true;
63 | }
64 | }
65 | else if ("resultMap".equals(targetElement))
66 | {
67 | if (JavaMapperCache.getInstance().resultMapExists(project, namespace, id))
68 | {
69 | return true;
70 | }
71 | }
72 |
73 | // Check XML mapper
74 | return elementExists(targetElement,
75 | MybatipseXmlUtil.getMapperDocument(project, namespace), id);
76 | }
77 | catch (XPathExpressionException e)
78 | {
79 | Activator.log(Status.ERROR, "Error occurred while validating reference: " + reference, e);
80 | }
81 | return false;
82 | }
83 |
84 | private static boolean elementExists(String targetElement, Set domDocs,
85 | String id) throws XPathExpressionException
86 | {
87 | for (IDOMDocument domDoc : domDocs)
88 | {
89 | if (XpathUtil.xpathBool(domDoc, "count(//" + targetElement + "[@id='" + id + "']) > 0"))
90 | return true;
91 | }
92 | return false;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/nature/MyBatisNature.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.nature;
13 |
14 | import org.eclipse.core.resources.ICommand;
15 | import org.eclipse.core.resources.IProject;
16 | import org.eclipse.core.resources.IProjectDescription;
17 | import org.eclipse.core.resources.IProjectNature;
18 | import org.eclipse.core.runtime.CoreException;
19 |
20 | /**
21 | * @author Iwao AVE!
22 | */
23 | public class MyBatisNature implements IProjectNature
24 | {
25 | public static final String NATURE_ID = "net.harawata.mybatipse.MyBatisNature";
26 |
27 | private IProject project;
28 |
29 | @Override
30 | public void configure() throws CoreException
31 | {
32 | IProjectDescription description = project.getDescription();
33 | ICommand[] commands = description.getBuildSpec();
34 | for (ICommand command : commands)
35 | {
36 | if (command.getBuilderName().equals(MybatipseIncrementalBuilder.BUILDER_ID))
37 | return; // Builder already registered.
38 | }
39 | // Add the builder to the project.
40 | ICommand[] newCommands = new ICommand[commands.length + 1];
41 | System.arraycopy(commands, 0, newCommands, 0, commands.length);
42 | ICommand command = description.newCommand();
43 | command.setBuilderName(MybatipseIncrementalBuilder.BUILDER_ID);
44 | newCommands[newCommands.length - 1] = command;
45 | description.setBuildSpec(newCommands);
46 | project.setDescription(description, null);
47 | }
48 |
49 | @Override
50 | public void deconfigure() throws CoreException
51 | {
52 | IProjectDescription description = project.getDescription();
53 | ICommand[] commands = description.getBuildSpec();
54 | for (int i = 0; i < commands.length; i++)
55 | {
56 | if (commands[i].getBuilderName().equals(MybatipseIncrementalBuilder.BUILDER_ID))
57 | {
58 | // Remove the builder from the project.
59 | ICommand[] newCommands = new ICommand[commands.length - 1];
60 | System.arraycopy(commands, 0, newCommands, 0, i);
61 | System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
62 | description.setBuildSpec(newCommands);
63 | project.setDescription(description, null);
64 | return;
65 | }
66 | }
67 | }
68 |
69 | @Override
70 | public IProject getProject()
71 | {
72 | return project;
73 | }
74 |
75 | @Override
76 | public void setProject(IProject project)
77 | {
78 | this.project = project;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/nature/MybatipseIncrementalBuilder.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.nature;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import java.text.MessageFormat;
17 | import java.util.Map;
18 |
19 | import org.eclipse.core.resources.IContainer;
20 | import org.eclipse.core.resources.IFile;
21 | import org.eclipse.core.resources.IProject;
22 | import org.eclipse.core.resources.IResource;
23 | import org.eclipse.core.resources.IResourceProxy;
24 | import org.eclipse.core.resources.IResourceProxyVisitor;
25 | import org.eclipse.core.resources.IncrementalProjectBuilder;
26 | import org.eclipse.core.runtime.CoreException;
27 | import org.eclipse.core.runtime.IProgressMonitor;
28 | import org.eclipse.core.runtime.OperationCanceledException;
29 | import org.eclipse.core.runtime.Status;
30 | import org.eclipse.core.runtime.content.IContentDescription;
31 | import org.eclipse.core.runtime.content.IContentType;
32 | import org.eclipse.wst.validation.ValidationFramework;
33 |
34 | import net.harawata.mybatipse.Activator;
35 | import net.harawata.mybatipse.bean.BeanPropertyCache;
36 | import net.harawata.mybatipse.mybatis.ConfigRegistry;
37 | import net.harawata.mybatipse.mybatis.MapperNamespaceCache;
38 | import net.harawata.mybatipse.mybatis.TypeAliasCache;
39 | import net.harawata.mybatipse.mybatis.XmlValidator;
40 |
41 | /**
42 | * @author Iwao AVE!
43 | */
44 | public class MybatipseIncrementalBuilder extends IncrementalProjectBuilder
45 | {
46 | public static final String BUILDER_ID = "net.harawata.mybatipse.MapperValidationBuilder";
47 |
48 | private int currentWork;
49 |
50 | @Override
51 | protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
52 | throws CoreException
53 | {
54 | // On full build, validation will be performed by validation builder.
55 | if (kind != FULL_BUILD)
56 | {
57 | // Mybatipse needs to validate all the mapper files, basically.
58 | validateAllMappers(monitor);
59 | }
60 | return null;
61 | }
62 |
63 | private void validateAllMappers(final IProgressMonitor monitor)
64 | {
65 | final int totalWork = countResources();
66 | monitor.beginTask("Mybatipse validation", totalWork);
67 | currentWork = 1;
68 |
69 | try
70 | {
71 | getProject().accept(new IResourceProxyVisitor()
72 | {
73 | private MessageFormat pattern = new MessageFormat("Validating {0}... ({1}/{2})");
74 |
75 | @Override
76 | public boolean visit(IResourceProxy proxy) throws CoreException
77 | {
78 | if (monitor.isCanceled())
79 | {
80 | forgetLastBuiltState();
81 | throw new OperationCanceledException();
82 | }
83 |
84 | monitor.subTask(pattern.format(new Object[]{
85 | proxy.getName(), currentWork, totalWork
86 | }));
87 |
88 | if (proxy.isDerived())
89 | return false;
90 |
91 | if (proxy.getType() == IResource.FILE && proxy.getName().endsWith(".xml"))
92 | {
93 | IFile file = (IFile)proxy.requestResource();
94 | IContentDescription contentDesc = file.getContentDescription();
95 | if (contentDesc != null)
96 | {
97 | IContentType contentType = contentDesc.getContentType();
98 | if (contentType != null && (contentType.isKindOf(configContentType)
99 | || contentType.isKindOf(mapperContentType)))
100 | {
101 | ValidationFramework.getDefault().validate(file, monitor);
102 | }
103 | }
104 | }
105 |
106 | monitor.worked(1);
107 | currentWork++;
108 | return true;
109 | }
110 | }, IContainer.NONE);
111 | }
112 | catch (CoreException e)
113 | {
114 | Activator.log(Status.ERROR, e.getMessage(), e);
115 | }
116 | finally
117 | {
118 | monitor.done();
119 | }
120 | }
121 |
122 | @Override
123 | protected void clean(IProgressMonitor monitor) throws CoreException
124 | {
125 | try
126 | {
127 | IProject project = getProject();
128 | project.accept(new IResourceProxyVisitor()
129 | {
130 | @Override
131 | public boolean visit(IResourceProxy proxy) throws CoreException
132 | {
133 | if (proxy.isDerived())
134 | return false;
135 |
136 | if (proxy.getType() == IResource.FILE && proxy.getName().endsWith(".xml"))
137 | {
138 | IFile file = (IFile)proxy.requestResource();
139 | IContentDescription contentDesc = file.getContentDescription();
140 | if (contentDesc != null)
141 | {
142 | IContentType contentType = contentDesc.getContentType();
143 | if (contentType != null && (contentType.isKindOf(configContentType)
144 | || contentType.isKindOf(springConfigContentType)))
145 | {
146 | file.deleteMarkers(XmlValidator.MARKER_ID, false, IResource.DEPTH_ZERO);
147 | }
148 | }
149 | }
150 | return true;
151 | }
152 | }, IContainer.NONE);
153 |
154 | TypeAliasCache.getInstance().remove(project);
155 | BeanPropertyCache.clearBeanPropertyCache(project);
156 | MapperNamespaceCache.getInstance().remove(project);
157 | ConfigRegistry.getInstance().remove(project);
158 | }
159 | catch (CoreException e)
160 | {
161 | Activator.log(Status.ERROR, e.getMessage(), e);
162 | }
163 | }
164 |
165 | private int countResources()
166 | {
167 | try
168 | {
169 | CountResourceVisitor visitor = new CountResourceVisitor();
170 | getProject().accept(visitor, IContainer.NONE);
171 | return visitor.count;
172 | }
173 | catch (CoreException e)
174 | {
175 | Activator.log(Status.WARNING, e.getMessage(), e);
176 | return IProgressMonitor.UNKNOWN;
177 | }
178 | }
179 |
180 | private class CountResourceVisitor implements IResourceProxyVisitor
181 | {
182 | int count;
183 |
184 | @Override
185 | public boolean visit(IResourceProxy proxy) throws CoreException
186 | {
187 | if (proxy.isDerived())
188 | return false;
189 | count++;
190 | return true;
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/nature/ToggleNatureCommand.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.nature;
13 |
14 | import java.util.Iterator;
15 |
16 | import org.eclipse.core.commands.AbstractHandler;
17 | import org.eclipse.core.commands.ExecutionEvent;
18 | import org.eclipse.core.commands.ExecutionException;
19 | import org.eclipse.core.commands.IHandler;
20 | import org.eclipse.core.resources.IProject;
21 | import org.eclipse.core.resources.IProjectDescription;
22 | import org.eclipse.core.runtime.CoreException;
23 | import org.eclipse.core.runtime.IAdaptable;
24 | import org.eclipse.core.runtime.Status;
25 | import org.eclipse.jface.viewers.ISelection;
26 | import org.eclipse.jface.viewers.IStructuredSelection;
27 | import org.eclipse.ui.IWorkbenchPage;
28 | import org.eclipse.ui.IWorkbenchWindow;
29 | import org.eclipse.ui.handlers.HandlerUtil;
30 |
31 | import net.harawata.mybatipse.Activator;
32 |
33 | /**
34 | * @author Iwao AVE!
35 | */
36 | public class ToggleNatureCommand extends AbstractHandler implements IHandler
37 | {
38 | private static final String TOGGLE_NATURE_PARAM = "net.harawata.mybatipse.ToggleNatureParam";
39 |
40 | @Override
41 | public Object execute(ExecutionEvent event) throws ExecutionException
42 | {
43 | String parameter = event.getParameter(TOGGLE_NATURE_PARAM);
44 | boolean addNature = "true".equals(parameter);
45 | IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
46 | IWorkbenchPage activePage = window.getActivePage();
47 | ISelection selection = activePage.getSelection();
48 | if (selection instanceof IStructuredSelection)
49 | {
50 | for (@SuppressWarnings("rawtypes")
51 | Iterator it = ((IStructuredSelection)selection).iterator(); it.hasNext();)
52 | {
53 | Object element = it.next();
54 | IProject project = null;
55 | if (element instanceof IProject)
56 | {
57 | project = (IProject)element;
58 | }
59 | else if (element instanceof IAdaptable)
60 | {
61 | project = (IProject)((IAdaptable)element).getAdapter(IProject.class);
62 | }
63 | if (project != null)
64 | {
65 | toggleNature(project, addNature);
66 | }
67 | }
68 | }
69 | return null;
70 | }
71 |
72 | private void toggleNature(IProject project, boolean addNature)
73 | {
74 | try
75 | {
76 | IProjectDescription description = project.getDescription();
77 | String[] natures = description.getNatureIds();
78 | for (int i = 0; i < natures.length; i++)
79 | {
80 | if (MyBatisNature.NATURE_ID.equals(natures[i]))
81 | {
82 | if (!addNature)
83 | {
84 | String[] newNatures = new String[natures.length - 1];
85 | System.arraycopy(natures, 0, newNatures, 0, i);
86 | System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
87 | description.setNatureIds(newNatures);
88 | project.setDescription(description, null);
89 | }
90 | return;
91 | }
92 | }
93 | if (addNature)
94 | {
95 | String[] newNatures = new String[natures.length + 1];
96 | System.arraycopy(natures, 0, newNatures, 0, natures.length);
97 | newNatures[natures.length] = MyBatisNature.NATURE_ID;
98 | description.setNatureIds(newNatures);
99 | project.setDescription(description, null);
100 | }
101 | }
102 | catch (CoreException e)
103 | {
104 | Activator.log(Status.ERROR, e.getMessage(), e);
105 | }
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/preference/CustomTypeAliasListEditor.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.preference;
13 |
14 | import org.eclipse.jface.dialogs.Dialog;
15 | import org.eclipse.jface.dialogs.InputDialog;
16 | import org.eclipse.jface.dialogs.TitleAreaDialog;
17 | import org.eclipse.swt.SWT;
18 | import org.eclipse.swt.layout.GridData;
19 | import org.eclipse.swt.layout.GridLayout;
20 | import org.eclipse.swt.widgets.Composite;
21 | import org.eclipse.swt.widgets.Control;
22 | import org.eclipse.swt.widgets.Label;
23 | import org.eclipse.swt.widgets.Shell;
24 | import org.eclipse.swt.widgets.Text;
25 | import org.eclipse.ui.PlatformUI;
26 |
27 | /**
28 | * @author Iwao AVE!
29 | */
30 | public class CustomTypeAliasListEditor extends EntryModifiableListEditor
31 | {
32 | private static final String TYPE_ALIAS_DIALOG_TITLE = "Specify package or fully qualified class name.";
33 |
34 | private static final String TYPE_ALIAS_DIALOG_MSG = "A package (e.g. pkg1.pkg2, com.company.*.domain) or "
35 | + "a fully qualified class name optionally with a custom alias (e.g. pkg.Person, pkg.Company:cmp)";
36 |
37 | public CustomTypeAliasListEditor(String name, String labelText, Composite parent)
38 | {
39 | super(name, labelText, parent);
40 | }
41 |
42 | @Override
43 | protected String createList(String[] items)
44 | {
45 | StringBuilder sb = new StringBuilder();
46 | for (String item : items)
47 | {
48 | sb.append(item).append('\t');
49 | }
50 | return sb.toString();
51 | }
52 |
53 | @Override
54 | protected String getNewInputObject()
55 | {
56 | NewTypeAliasDialog dialog = new NewTypeAliasDialog(getShell());
57 | if (Dialog.OK == dialog.open())
58 | {
59 | return dialog.getEntry();
60 | }
61 | return null;
62 | }
63 |
64 | @Override
65 | protected String[] parseString(String stringList)
66 | {
67 | return stringList.split("\t");
68 | }
69 |
70 | @Override
71 | protected String getModifiedEntry(String original)
72 | {
73 | InputDialog entryDialog = new InputDialog(
74 | PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), TYPE_ALIAS_DIALOG_TITLE,
75 | TYPE_ALIAS_DIALOG_MSG, original, null);
76 | if (entryDialog.open() == InputDialog.OK)
77 | {
78 | return entryDialog.getValue();
79 | }
80 | return null;
81 | }
82 |
83 | public void setItemsAsString(String str)
84 | {
85 | getList().setItems(parseString(str));
86 | }
87 |
88 | public String getItemsAsString()
89 | {
90 | return createList(getList().getItems());
91 | }
92 |
93 | class NewTypeAliasDialog extends TitleAreaDialog
94 | {
95 | private Text entryText;
96 |
97 | private String entry;
98 |
99 | public NewTypeAliasDialog(Shell parentShell)
100 | {
101 | super(parentShell);
102 | }
103 |
104 | @Override
105 | protected Control createDialogArea(Composite parent)
106 | {
107 | Composite area = (Composite)super.createDialogArea(parent);
108 | Composite container = new Composite(area, SWT.NONE);
109 | container.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, true));
110 | GridLayout layout = new GridLayout(2, false);
111 | container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
112 | container.setLayout(layout);
113 | createTypeAliasEntry(container);
114 | setTitle(TYPE_ALIAS_DIALOG_TITLE);
115 | setMessage(TYPE_ALIAS_DIALOG_MSG);
116 | return area;
117 | }
118 |
119 | @Override
120 | protected void okPressed()
121 | {
122 | entry = entryText.getText();
123 | super.okPressed();
124 | }
125 |
126 | @Override
127 | protected boolean isResizable()
128 | {
129 | return true;
130 | }
131 |
132 | private void createTypeAliasEntry(Composite container)
133 | {
134 | Label entryLabel = new Label(container, SWT.NONE);
135 | entryLabel.setText("Package or Class");
136 |
137 | GridData entryData = new GridData();
138 | entryData.grabExcessHorizontalSpace = true;
139 | entryData.horizontalAlignment = GridData.FILL;
140 |
141 | entryText = new Text(container, SWT.BORDER);
142 | entryText.setLayoutData(entryData);
143 | }
144 |
145 | public String getEntry()
146 | {
147 | return entry;
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/preference/EntryModifiableListEditor.java:
--------------------------------------------------------------------------------
1 |
2 | package net.harawata.mybatipse.preference;
3 |
4 | import org.eclipse.jface.dialogs.IDialogConstants;
5 | import org.eclipse.jface.preference.ListEditor;
6 | import org.eclipse.swt.SWT;
7 | import org.eclipse.swt.events.DisposeEvent;
8 | import org.eclipse.swt.events.DisposeListener;
9 | import org.eclipse.swt.events.SelectionAdapter;
10 | import org.eclipse.swt.events.SelectionEvent;
11 | import org.eclipse.swt.layout.GridData;
12 | import org.eclipse.swt.widgets.Button;
13 | import org.eclipse.swt.widgets.Composite;
14 | import org.eclipse.swt.widgets.List;
15 |
16 | /**
17 | * This class extends {@link ListEditor} to enable editing of entries.
18 | *
19 | * @author Sandip V. Chitale
20 | * @see http://sandipchitale.blogspot.jp/2008/09/enhanced-listeditor-implementation.html
21 | */
22 | public abstract class EntryModifiableListEditor extends ListEditor
23 | {
24 |
25 | public EntryModifiableListEditor(String name, String labelText, Composite parent)
26 | {
27 | super(name, labelText, parent);
28 | }
29 |
30 | /**
31 | * The subclasses must override this to return the modified entry.
32 | *
33 | * @param original the new entry
34 | * @return the modified entry. Return null to prevent modification.
35 | */
36 | protected abstract String getModifiedEntry(String original);
37 |
38 | private Button editButton;
39 |
40 | private List commandListControl;
41 |
42 | @Override
43 | public Composite getButtonBoxControl(Composite parent)
44 | {
45 | Composite buttonBoxControl = super.getButtonBoxControl(parent);
46 | if (editButton == null)
47 | {
48 | editButton = createPushButton(buttonBoxControl, "Edit..."); // TODO I18N
49 | editButton.setEnabled(false);
50 | editButton.addSelectionListener(new SelectionAdapter()
51 | {
52 | @Override
53 | public void widgetSelected(SelectionEvent e)
54 | {
55 | if (commandListControl.getSelectionCount() == 1)
56 | {
57 | String modified = getModifiedEntry(commandListControl.getSelection()[0]);
58 | if (modified != null)
59 | {
60 | int selectedIndex = commandListControl.getSelectionIndex();
61 | commandListControl.remove(selectedIndex);
62 | commandListControl.add(modified, selectedIndex);
63 | }
64 | }
65 | }
66 | });
67 | buttonBoxControl.addDisposeListener(new DisposeListener()
68 | {
69 | public void widgetDisposed(DisposeEvent event)
70 | {
71 | editButton = null;
72 | }
73 | });
74 | }
75 | return buttonBoxControl;
76 | }
77 |
78 | /**
79 | * Helper method to create a push button.
80 | *
81 | * @param parent the parent control
82 | * @param key the resource name used to supply the button's label text
83 | * @return Button
84 | */
85 | private Button createPushButton(Composite parent, String key)
86 | {
87 | Button button = new Button(parent, SWT.PUSH);
88 | button.setText(key);
89 | button.setFont(parent.getFont());
90 | GridData data = new GridData(GridData.FILL_HORIZONTAL);
91 | int widthHint = convertHorizontalDLUsToPixels(button, IDialogConstants.BUTTON_WIDTH);
92 | data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
93 | button.setLayoutData(data);
94 | return button;
95 | }
96 |
97 | @Override
98 | public List getListControl(Composite parent)
99 | {
100 | List listControl = super.getListControl(parent);
101 | if (commandListControl == null)
102 | {
103 | commandListControl = listControl;
104 | commandListControl.addSelectionListener(new SelectionAdapter()
105 | {
106 | @Override
107 | public void widgetSelected(SelectionEvent e)
108 | {
109 | editButton.setEnabled(commandListControl.getSelectionCount() == 1);
110 | }
111 | });
112 | }
113 | return listControl;
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/preference/MybatipsePreferenceInitializer.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.preference;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
17 | import org.eclipse.core.runtime.preferences.DefaultScope;
18 | import org.eclipse.core.runtime.preferences.IEclipsePreferences;
19 |
20 | /**
21 | * @author Iwao AVE!
22 | */
23 | public class MybatipsePreferenceInitializer extends AbstractPreferenceInitializer
24 | {
25 |
26 | @Override
27 | public void initializeDefaultPreferences()
28 | {
29 | IEclipsePreferences node = DefaultScope.INSTANCE.getNode(PLUGIN_ID);
30 | // node.put(PREF_PRIMARY_CONFIG_PATH, ""); //$NON-NLS-N$
31 | // node.put(PREF_DISABLE_TYPE_ALIAS_RESOLUTION, "false"); //$NON-NLS-N$
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/preference/MybatipsePreferencePage.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.preference;
13 |
14 | import static net.harawata.mybatipse.MybatipseConstants.*;
15 |
16 | import org.eclipse.core.runtime.preferences.InstanceScope;
17 | import org.eclipse.jface.preference.IPreferenceStore;
18 | import org.eclipse.swt.widgets.Composite;
19 | import org.eclipse.ui.IWorkbench;
20 | import org.eclipse.ui.IWorkbenchPreferencePage;
21 | import org.eclipse.ui.preferences.ScopedPreferenceStore;
22 |
23 | /**
24 | * @author Iwao AVE!
25 | */
26 | public class MybatipsePreferencePage extends ScopedFieldEditorPreferencePage
27 | implements IWorkbenchPreferencePage
28 | {
29 | private CustomTypeAliasListEditor customTypeAliases;
30 |
31 | public MybatipsePreferencePage()
32 | {
33 | super(GRID);
34 | }
35 |
36 | @Override
37 | protected IPreferenceStore doGetPreferenceStore()
38 | {
39 | return new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_ID);
40 | }
41 |
42 | @Override
43 | public void init(IWorkbench workbench)
44 | {
45 | setDescription("MyBatipse Settings");
46 | }
47 |
48 | @Override
49 | protected void createFieldEditors()
50 | {
51 | Composite parent = getFieldEditorParent();
52 | customTypeAliases = new CustomTypeAliasListEditor(PREF_CUSTOM_TYPE_ALIASES,
53 | "Custom type aliases", parent);
54 | addField(customTypeAliases);
55 | // if (isProjectPropertyPage())
56 | // {
57 | // customTypeAliases.setItemsAsString(getPreferenceStore().getString(
58 | // PREF_CUSTOM_TYPE_ALIASES));
59 | // }
60 | }
61 |
62 | @Override
63 | public boolean performOk()
64 | {
65 | if (isProjectPropertyPage())
66 | {
67 | IPreferenceStore store = getPreferenceStore();
68 | store.setValue(PREF_CUSTOM_TYPE_ALIASES, customTypeAliases.getItemsAsString());
69 | }
70 | return super.performOk();
71 | }
72 |
73 | @Override
74 | protected String getPluginId()
75 | {
76 | return PLUGIN_ID;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/preference/ScopedFieldEditorPreferencePage.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.preference;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | import org.eclipse.core.resources.IProject;
18 | import org.eclipse.core.resources.ProjectScope;
19 | import org.eclipse.core.runtime.IAdaptable;
20 | import org.eclipse.jdt.core.IJavaProject;
21 | import org.eclipse.jface.preference.FieldEditor;
22 | import org.eclipse.jface.preference.FieldEditorPreferencePage;
23 | import org.eclipse.swt.SWT;
24 | import org.eclipse.swt.events.SelectionAdapter;
25 | import org.eclipse.swt.events.SelectionEvent;
26 | import org.eclipse.swt.layout.GridData;
27 | import org.eclipse.swt.layout.GridLayout;
28 | import org.eclipse.swt.widgets.Button;
29 | import org.eclipse.swt.widgets.Composite;
30 | import org.eclipse.swt.widgets.Control;
31 | import org.eclipse.ui.IWorkbenchPropertyPage;
32 | import org.eclipse.ui.preferences.ScopedPreferenceStore;
33 |
34 | /**
35 | * @see https://www.eclipse.org/articles/Article-Mutatis-mutandis/overlay-pages.html
36 | * @author Iwao AVE!
37 | */
38 | public abstract class ScopedFieldEditorPreferencePage extends FieldEditorPreferencePage
39 | implements IWorkbenchPropertyPage
40 | {
41 | public static final String USE_PROJECT_SETTINGS = "useProjectSettings";
42 |
43 | private Button useWorkspaceSettingsButton;
44 |
45 | private Button useProjectSettingsButton;
46 |
47 | private List editors = new ArrayList();
48 |
49 | private IAdaptable element;
50 |
51 | protected Control createContents(Composite parent)
52 | {
53 | if (isProjectPropertyPage())
54 | {
55 | createProjectSpecificControls(parent);
56 | }
57 | return super.createContents(parent);
58 | }
59 |
60 | private void createProjectSpecificControls(Composite parent)
61 | {
62 | Composite comp = new Composite(parent, SWT.NONE);
63 | GridLayout layout = new GridLayout(2, false);
64 | layout.marginHeight = 0;
65 | layout.marginWidth = 0;
66 | comp.setLayout(layout);
67 | comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
68 | Composite radioGroup = new Composite(comp, SWT.NONE);
69 | radioGroup.setLayout(new GridLayout());
70 | radioGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
71 | useWorkspaceSettingsButton = createRadioButton(radioGroup, "Use workspace settings");
72 | useProjectSettingsButton = createRadioButton(radioGroup, "Use project settings");
73 |
74 | if (getPreferenceStore().getBoolean(USE_PROJECT_SETTINGS))
75 | {
76 | useProjectSettingsButton.setSelection(true);
77 | }
78 | else
79 | {
80 | useWorkspaceSettingsButton.setSelection(true);
81 | }
82 | }
83 |
84 | private Button createRadioButton(Composite parent, String label)
85 | {
86 | final Button button = new Button(parent, SWT.RADIO);
87 | button.setText(label);
88 | button.addSelectionListener(new SelectionAdapter()
89 | {
90 | public void widgetSelected(SelectionEvent e)
91 | {
92 | updateFieldEditors();
93 | }
94 | });
95 | return button;
96 | }
97 |
98 | private void updateFieldEditors()
99 | {
100 | boolean enabled = useProjectSettingsButton.getSelection();
101 | updateFieldEditors(enabled);
102 | }
103 |
104 | protected void updateFieldEditors(boolean enabled)
105 | {
106 | Composite parent = getFieldEditorParent();
107 | for (FieldEditor editor : editors)
108 | {
109 | editor.setEnabled(enabled, parent);
110 | }
111 | }
112 |
113 | @Override
114 | public void createControl(Composite parent)
115 | {
116 | super.createControl(parent);
117 | if (isProjectPropertyPage())
118 | {
119 | updateFieldEditors();
120 | }
121 | }
122 |
123 | @Override
124 | public boolean performOk()
125 | {
126 | boolean result = super.performOk();
127 | if (result && isProjectPropertyPage())
128 | {
129 | // try
130 | // {
131 | ScopedPreferenceStore store = (ScopedPreferenceStore)getPreferenceStore();
132 | store.setValue(USE_PROJECT_SETTINGS, useProjectSettingsButton.getSelection());
133 | // store.save();
134 | // }
135 | // catch (IOException e)
136 | // {
137 | // e.printStackTrace();
138 | // }
139 | }
140 | return result;
141 | }
142 |
143 | @Override
144 | protected void performDefaults()
145 | {
146 | if (isProjectPropertyPage())
147 | {
148 | useWorkspaceSettingsButton.setSelection(true);
149 | useProjectSettingsButton.setSelection(false);
150 | updateFieldEditors();
151 | }
152 | super.performDefaults();
153 | }
154 |
155 | @Override
156 | protected void addField(FieldEditor editor)
157 | {
158 | editors.add(editor);
159 | super.addField(editor);
160 | }
161 |
162 | @Override
163 | public IAdaptable getElement()
164 | {
165 | return element;
166 | }
167 |
168 | @Override
169 | public void setElement(IAdaptable element)
170 | {
171 | this.element = element;
172 | setPreferenceStore(
173 | new ScopedPreferenceStore(new ProjectScope(getProject()), getPluginId()));
174 | }
175 |
176 | protected IProject getProject()
177 | {
178 | return element instanceof IJavaProject ? ((IJavaProject)element).getProject()
179 | : (IProject)element;
180 | }
181 |
182 | public boolean isProjectPropertyPage()
183 | {
184 | return element != null;
185 | }
186 |
187 | public ScopedFieldEditorPreferencePage(int style)
188 | {
189 | super(style);
190 | }
191 |
192 | public ScopedFieldEditorPreferencePage(String title, int style)
193 | {
194 | super(title, style);
195 | }
196 |
197 | protected abstract String getPluginId();
198 | }
199 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/quickassist/AddParamQuickAssist.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.quickassist;
13 |
14 | import java.util.List;
15 |
16 | import org.eclipse.core.runtime.Status;
17 | import org.eclipse.jdt.core.dom.AST;
18 | import org.eclipse.jdt.core.dom.Annotation;
19 | import org.eclipse.jdt.core.dom.CompilationUnit;
20 | import org.eclipse.jdt.core.dom.IExtendedModifier;
21 | import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
22 | import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
23 | import org.eclipse.jdt.core.dom.StringLiteral;
24 | import org.eclipse.jface.text.BadLocationException;
25 | import org.eclipse.jface.text.IDocument;
26 | import org.eclipse.text.edits.MalformedTreeException;
27 | import org.eclipse.text.edits.TextEdit;
28 |
29 | import net.harawata.mybatipse.Activator;
30 | import net.harawata.mybatipse.MybatipseConstants;
31 | import net.harawata.mybatipse.quickassist.JavaQuickAssistProcessor.MapperMethod;
32 |
33 | final class AddParamQuickAssist extends QuickAssistCompletionProposal
34 | {
35 | private CompilationUnit astNode;
36 |
37 | private MapperMethod method;
38 |
39 | @SuppressWarnings("unchecked")
40 | @Override
41 | public void apply(IDocument document)
42 | {
43 | List params = method.parameters();
44 | for (SingleVariableDeclaration param : params)
45 | {
46 | List modifiers = param.modifiers();
47 | if (!hasParamAnnotation(modifiers))
48 | {
49 | if (MybatipseConstants.TYPE_ROW_BOUNDS
50 | .equals(param.resolveBinding().getType().getQualifiedName()))
51 | continue;
52 | AST ast = param.getAST();
53 | SingleMemberAnnotation annotation = ast.newSingleMemberAnnotation();
54 | annotation.setTypeName(ast.newName("Param"));
55 | StringLiteral paramValue = ast.newStringLiteral();
56 | paramValue.setLiteralValue(param.getName().getFullyQualifiedName());
57 | annotation.setValue(paramValue);
58 | param.modifiers().add(annotation);
59 | }
60 | }
61 | TextEdit textEdit = astNode.rewrite(document, null);
62 | try
63 | {
64 | textEdit.apply(document);
65 | }
66 | catch (MalformedTreeException e)
67 | {
68 | Activator.log(Status.ERROR, e.getMessage(), e);
69 | }
70 | catch (BadLocationException e)
71 | {
72 | Activator.log(Status.ERROR, e.getMessage(), e);
73 | }
74 | }
75 |
76 | private boolean hasParamAnnotation(List modifiers)
77 | {
78 | for (IExtendedModifier modifier : modifiers)
79 | {
80 | if (modifier.isAnnotation()
81 | && "Param".equals(((Annotation)modifier).getTypeName().getFullyQualifiedName()))
82 | {
83 | return true;
84 | }
85 | }
86 | return false;
87 | }
88 |
89 | public AddParamQuickAssist(String displayString, MapperMethod method, CompilationUnit astNode)
90 | {
91 | super(displayString);
92 | this.method = method;
93 | this.astNode = astNode;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/quickassist/MoveResultMapToXmlQuickAssist.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.quickassist;
13 |
14 | import java.io.IOException;
15 | import java.io.UnsupportedEncodingException;
16 |
17 | import javax.xml.xpath.XPathExpressionException;
18 |
19 | import org.eclipse.core.resources.IFile;
20 | import org.eclipse.core.runtime.CoreException;
21 | import org.eclipse.core.runtime.Status;
22 | import org.eclipse.jdt.core.dom.CompilationUnit;
23 | import org.eclipse.jface.dialogs.IInputValidator;
24 | import org.eclipse.jface.dialogs.InputDialog;
25 | import org.eclipse.jface.dialogs.MessageDialog;
26 | import org.eclipse.jface.text.BadLocationException;
27 | import org.eclipse.jface.text.IDocument;
28 | import org.eclipse.jface.window.Window;
29 | import org.eclipse.swt.widgets.Display;
30 | import org.eclipse.swt.widgets.Shell;
31 | import org.eclipse.text.edits.TextEdit;
32 | import org.eclipse.wst.sse.core.StructuredModelManager;
33 | import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
34 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
35 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
36 | import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
37 | import org.w3c.dom.Element;
38 | import org.w3c.dom.Node;
39 |
40 | import net.harawata.mybatipse.Activator;
41 | import net.harawata.mybatipse.quickassist.JavaQuickAssistProcessor.MapperMethod;
42 | import net.harawata.mybatipse.quickassist.JavaQuickAssistProcessor.ResultAnno;
43 | import net.harawata.mybatipse.util.XpathUtil;
44 |
45 | @SuppressWarnings("restriction")
46 | final class MoveResultMapToXmlQuickAssist extends QuickAssistCompletionProposal
47 | {
48 | private IFile xmlMapperFile;
49 |
50 | private MapperMethod method;
51 |
52 | private CompilationUnit astNode;
53 |
54 | @Override
55 | public void apply(IDocument document)
56 | {
57 | try
58 | {
59 | if (addXmlResultMap(xmlMapperFile))
60 | {
61 | deleteResultsAnnotation(document);
62 | }
63 | }
64 | catch (Exception e)
65 | {
66 | Activator.log(Status.ERROR, e.getMessage(), e);
67 | }
68 | }
69 |
70 | private void deleteResultsAnnotation(IDocument document) throws BadLocationException
71 | {
72 | if (method.getResultsAnno() != null)
73 | {
74 | method.getResultsAnno().delete();
75 | }
76 | if (method.getConstructorArgsAnno() != null)
77 | {
78 | method.getConstructorArgsAnno().delete();
79 | }
80 | TextEdit textEdit = astNode.rewrite(document, null);
81 | textEdit.apply(document);
82 | }
83 |
84 | private boolean addXmlResultMap(final IFile xmlMapperFile)
85 | throws IOException, CoreException, UnsupportedEncodingException, XPathExpressionException
86 | {
87 | final IStructuredModel model = StructuredModelManager.getModelManager()
88 | .getModelForEdit(xmlMapperFile);
89 | if (model == null || !(model instanceof IDOMModel))
90 | {
91 | Activator.openDialog(MessageDialog.ERROR, "Cannot move result map to XML mapper",
92 | "Failed to create a model for the XML mapper "
93 | + xmlMapperFile.getProjectRelativePath().toString());
94 | return false;
95 | }
96 | try
97 | {
98 | final IDOMDocument mapperDoc = ((IDOMModel)model).getDocument();
99 | String id = method.getResultsId();
100 | if (id == null)
101 | {
102 | Shell shell = Display.getDefault().getActiveShell();
103 | InputDialog dialog = new InputDialog(shell, "Enter result map id",
104 | "Specify id of the resultMap element", "", new IInputValidator()
105 | {
106 | @Override
107 | public String isValid(String newText)
108 | {
109 | if (newText.length() == 0)
110 | {
111 | return "Please enter result map id.";
112 | }
113 | try
114 | {
115 | Node domNode = XpathUtil.xpathNode(mapperDoc,
116 | "//resultMap[@id='" + newText + "']");
117 | if (domNode != null)
118 | {
119 | return "A resultMap with id '" + newText
120 | + "' is already defined. Id must be unique.";
121 | }
122 | }
123 | catch (XPathExpressionException e)
124 | {
125 | return "Error occurred while looking for a resultMap with the same id. "
126 | + "Did you use some unusual characters or something?";
127 | }
128 | return null;
129 | }
130 | });
131 | if (dialog.open() == Window.OK)
132 | id = dialog.getValue();
133 | else
134 | return false;
135 | }
136 |
137 | model.beginRecording(this);
138 | model.aboutToChangeModel();
139 | Element root = mapperDoc.getDocumentElement();
140 | Element element = createResultMapElement(mapperDoc, id);
141 | root.appendChild(element);
142 | String delimiter = model.getStructuredDocument().getLineDelimiter();
143 | root.appendChild(mapperDoc.createTextNode(delimiter));
144 | new FormatProcessorXML().formatNode(element);
145 | }
146 | finally
147 | {
148 | if (model != null)
149 | {
150 | model.changedModel();
151 | if (!model.isSharedForEdit() && model.isSaveNeeded())
152 | {
153 | model.save();
154 | }
155 | model.endRecording(this);
156 | model.releaseFromEdit();
157 | }
158 | }
159 | return true;
160 | }
161 |
162 | private Element createResultMapElement(IDOMDocument mapperDoc, String id)
163 | {
164 | Element resultMap = mapperDoc.createElement("resultMap");
165 | resultMap.setAttribute("id", id);
166 | resultMap.setAttribute("type", method.getReturnTypeStr());
167 | if (!method.getConstructorArgs().isEmpty())
168 | {
169 | Element constructor = mapperDoc.createElement("constructor");
170 | for (ResultAnno result : method.getConstructorArgs())
171 | {
172 | Element element;
173 | if (result.isId())
174 | {
175 | element = mapperDoc.createElement("idArg");
176 | }
177 | else
178 | {
179 | element = mapperDoc.createElement("arg");
180 | }
181 | setResultAttrs(result, element);
182 | constructor.appendChild(element);
183 | }
184 | resultMap.appendChild(constructor);
185 | }
186 | for (ResultAnno result : method.getResultAnnos())
187 | {
188 | Element element;
189 | if (result.isId())
190 | {
191 | element = mapperDoc.createElement("id");
192 | }
193 | else if (result.isAssociation())
194 | {
195 | element = mapperDoc.createElement("association");
196 | }
197 | else if (result.isCollection())
198 | {
199 | element = mapperDoc.createElement("collection");
200 | }
201 | else
202 | {
203 | element = mapperDoc.createElement("result");
204 | }
205 | setResultAttrs(result, element);
206 | resultMap.appendChild(element);
207 | }
208 | return resultMap;
209 | }
210 |
211 | protected void setResultAttrs(ResultAnno result, Element element)
212 | {
213 | setAttr(element, "property", result.getProperty());
214 | setAttr(element, "column", result.getColumn());
215 | setAttr(element, "select", result.getSelectId());
216 | setAttr(element, "javaType", result.getJavaType());
217 | setAttr(element, "jdbcType", result.getJdbcType());
218 | setAttr(element, "fetchType", result.getFetchType());
219 | setAttr(element, "typeHandler", result.getTypeHandler());
220 | setAttr(element, "resultMap", result.getResultMap());
221 | }
222 |
223 | private void setAttr(Element element, String name, String value)
224 | {
225 | if (value != null)
226 | element.setAttribute(name, value);
227 | }
228 |
229 | MoveResultMapToXmlQuickAssist(
230 | String displayString,
231 | IFile xmlMapperFile,
232 | MapperMethod method,
233 | CompilationUnit astNode)
234 | {
235 | super(displayString);
236 | this.xmlMapperFile = xmlMapperFile;
237 | this.method = method;
238 | this.astNode = astNode;
239 | }
240 | }
241 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/quickassist/MoveStatementToXmlQuickAssist.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.quickassist;
13 |
14 | import java.io.IOException;
15 | import java.io.UnsupportedEncodingException;
16 |
17 | import javax.xml.xpath.XPathExpressionException;
18 |
19 | import org.eclipse.core.resources.IFile;
20 | import org.eclipse.core.runtime.CoreException;
21 | import org.eclipse.core.runtime.Status;
22 | import org.eclipse.jdt.core.dom.CompilationUnit;
23 | import org.eclipse.jdt.core.dom.MethodDeclaration;
24 | import org.eclipse.jface.dialogs.MessageDialog;
25 | import org.eclipse.jface.text.BadLocationException;
26 | import org.eclipse.jface.text.IDocument;
27 | import org.eclipse.text.edits.TextEdit;
28 | import org.eclipse.wst.sse.core.StructuredModelManager;
29 | import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
30 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
31 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
32 | import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
33 | import org.w3c.dom.Element;
34 | import org.w3c.dom.Node;
35 | import org.w3c.dom.Text;
36 |
37 | import net.harawata.mybatipse.Activator;
38 | import net.harawata.mybatipse.quickassist.JavaQuickAssistProcessor.MapperMethod;
39 | import net.harawata.mybatipse.util.XpathUtil;
40 |
41 | @SuppressWarnings("restriction")
42 | final class MoveStatementToXmlQuickAssist extends QuickAssistCompletionProposal
43 | {
44 | private IFile xmlMapperFile;
45 |
46 | private MapperMethod method;
47 |
48 | private CompilationUnit astNode;
49 |
50 | @Override
51 | public void apply(IDocument document)
52 | {
53 | if (method.getResultsAnno() != null && method.getResultsId() == null)
54 | {
55 | Activator.openDialog(MessageDialog.ERROR, "Cannot move result map to XML mapper",
56 | "You must specify 'id' in @Results before moving the statement.");
57 | return;
58 | }
59 | try
60 | {
61 | if (addXmlStatement(xmlMapperFile))
62 | {
63 | deleteStatementAnnotation(document);
64 | }
65 | }
66 | catch (Exception e)
67 | {
68 | Activator.log(Status.ERROR, e.getMessage(), e);
69 | }
70 | }
71 |
72 | private void deleteStatementAnnotation(IDocument document) throws BadLocationException
73 | {
74 | method.getStatementAnno().delete();
75 | TextEdit textEdit = astNode.rewrite(document, null);
76 | textEdit.apply(document);
77 | }
78 |
79 | private boolean addXmlStatement(IFile xmlMapperFile)
80 | throws IOException, CoreException, UnsupportedEncodingException, XPathExpressionException
81 | {
82 | IStructuredModel model = StructuredModelManager.getModelManager()
83 | .getModelForEdit(xmlMapperFile);
84 | if (model == null)
85 | {
86 | Activator.openDialog(MessageDialog.ERROR, "Cannot move statement to XML mapper",
87 | "Failed to create a model for the XML mapper "
88 | + xmlMapperFile.getProjectRelativePath().toString());
89 | return false;
90 | }
91 |
92 | try
93 | {
94 | model.beginRecording(this);
95 | model.aboutToChangeModel();
96 | if (model instanceof IDOMModel)
97 | {
98 | String delimiter = model.getStructuredDocument().getLineDelimiter();
99 | IDOMDocument mapperDoc = ((IDOMModel)model).getDocument();
100 | String id = method.getMethodDeclaration().getName().getFullyQualifiedName();
101 | Node domNode = XpathUtil.xpathNode(mapperDoc, "//*[@id='" + id + "']");
102 | if (domNode != null)
103 | {
104 | Activator.openDialog(MessageDialog.ERROR, "Cannot move statement to XML mapper",
105 | "An element with id '" + id + "' is already defined in "
106 | + xmlMapperFile.getProjectRelativePath().toString());
107 | return false;
108 | }
109 | Element root = mapperDoc.getDocumentElement();
110 | Element element = createStatementElement(mapperDoc, delimiter);
111 | root.appendChild(element);
112 | root.appendChild(mapperDoc.createTextNode(delimiter));
113 | new FormatProcessorXML().formatNode(element);
114 | }
115 | }
116 | finally
117 | {
118 | model.changedModel();
119 | if (!model.isSharedForEdit() && model.isSaveNeeded())
120 | {
121 | model.save();
122 | }
123 | model.endRecording(this);
124 | model.releaseFromEdit();
125 | }
126 | return true;
127 | }
128 |
129 | private Element createStatementElement(IDOMDocument mapperDoc, String delimiter)
130 | {
131 | String statement = method.getStatementAnnoName().toLowerCase();
132 | Element element = mapperDoc.createElement(statement);
133 | MethodDeclaration methodDeclaration = method.getMethodDeclaration();
134 | element.setAttribute("id", methodDeclaration.getName().toString());
135 | if (method.isSelect())
136 | {
137 | if (method.getResultMap() != null)
138 | {
139 | element.setAttribute("resultMap", method.getResultMap());
140 | }
141 | else if (method.getResultsId() != null)
142 | {
143 | element.setAttribute("resultMap", method.getResultsId());
144 | }
145 | else
146 | {
147 | element.setAttribute("resultType", method.getReturnTypeStr());
148 | }
149 | }
150 | Text sqlText = mapperDoc.createTextNode(delimiter + method.getStatement() + delimiter);
151 | element.appendChild(sqlText);
152 | return element;
153 | }
154 |
155 | MoveStatementToXmlQuickAssist(
156 | String displayString,
157 | IFile xmlMapperFile,
158 | MapperMethod method,
159 | CompilationUnit astNode)
160 | {
161 | super(displayString);
162 | this.xmlMapperFile = xmlMapperFile;
163 | this.method = method;
164 | this.astNode = astNode;
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/quickassist/QuickAssistCompletionProposal.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.quickassist;
13 |
14 | import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
15 | import org.eclipse.jface.text.IDocument;
16 | import org.eclipse.jface.text.contentassist.IContextInformation;
17 | import org.eclipse.swt.graphics.Image;
18 | import org.eclipse.swt.graphics.Point;
19 |
20 | import net.harawata.mybatipse.Activator;
21 |
22 | abstract class QuickAssistCompletionProposal implements IJavaCompletionProposal
23 | {
24 | private String displayString;
25 |
26 | QuickAssistCompletionProposal(String displayString)
27 | {
28 | super();
29 | this.displayString = displayString;
30 | }
31 |
32 | @Override
33 | public Point getSelection(IDocument document)
34 | {
35 | return null;
36 | }
37 |
38 | @Override
39 | public String getAdditionalProposalInfo()
40 | {
41 | return null;
42 | }
43 |
44 | @Override
45 | public String getDisplayString()
46 | {
47 | return displayString;
48 | }
49 |
50 | @Override
51 | public Image getImage()
52 | {
53 | return Activator.getIcon();
54 | }
55 |
56 | @Override
57 | public IContextInformation getContextInformation()
58 | {
59 | return null;
60 | }
61 |
62 | @Override
63 | public int getRelevance()
64 | {
65 | return 500;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/ElementRenameInfo.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring;
13 |
14 | import org.eclipse.jdt.core.IJavaProject;
15 |
16 | /**
17 | * @author Iwao AVE!
18 | */
19 | public class ElementRenameInfo
20 | {
21 | private String namespace;
22 |
23 | private String oldId;
24 |
25 | private String newId;
26 |
27 | private IJavaProject project;
28 |
29 | public String getNamespace()
30 | {
31 | return namespace;
32 | }
33 |
34 | public void setNamespace(String namespace)
35 | {
36 | this.namespace = namespace;
37 | }
38 |
39 | public String getOldId()
40 | {
41 | return oldId;
42 | }
43 |
44 | public void setOldId(String oldId)
45 | {
46 | this.oldId = oldId;
47 | }
48 |
49 | public String getNewId()
50 | {
51 | return newId;
52 | }
53 |
54 | public void setNewId(String newId)
55 | {
56 | this.newId = newId;
57 | }
58 |
59 | public IJavaProject getProject()
60 | {
61 | return project;
62 | }
63 |
64 | public void setProject(IJavaProject project)
65 | {
66 | this.project = project;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/ElementRenameRefactoring.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring;
13 |
14 | import java.util.HashMap;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.Map.Entry;
18 |
19 | import org.eclipse.core.resources.IFile;
20 | import org.eclipse.core.runtime.CoreException;
21 | import org.eclipse.core.runtime.IProgressMonitor;
22 | import org.eclipse.core.runtime.OperationCanceledException;
23 | import org.eclipse.ltk.core.refactoring.Change;
24 | import org.eclipse.ltk.core.refactoring.CompositeChange;
25 | import org.eclipse.ltk.core.refactoring.Refactoring;
26 | import org.eclipse.ltk.core.refactoring.RefactoringStatus;
27 | import org.eclipse.ltk.core.refactoring.TextChange;
28 | import org.eclipse.ltk.core.refactoring.TextFileChange;
29 | import org.eclipse.text.edits.MultiTextEdit;
30 | import org.eclipse.text.edits.ReplaceEdit;
31 | import org.eclipse.text.edits.TextEdit;
32 |
33 | import net.harawata.mybatipse.refactoring.collector.RenameEditCollector;
34 |
35 | /**
36 | * @author Iwao AVE!
37 | */
38 | public class ElementRenameRefactoring extends Refactoring
39 | {
40 | protected final RenameEditCollector collector;
41 |
42 | protected final Map> editsPerFiles = new HashMap>();
43 |
44 | public ElementRenameRefactoring(RenameEditCollector collector)
45 | {
46 | super();
47 | this.collector = collector;
48 | }
49 |
50 | @Override
51 | public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
52 | throws CoreException, OperationCanceledException
53 | {
54 | return new RefactoringStatus();
55 | }
56 |
57 | @Override
58 | public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
59 | throws CoreException, OperationCanceledException
60 | {
61 | try
62 | {
63 | return collector.collect(editsPerFiles, pm);
64 | }
65 | finally
66 | {
67 | pm.done();
68 | }
69 | }
70 |
71 | @Override
72 | public Change createChange(IProgressMonitor pm)
73 | throws CoreException, OperationCanceledException
74 | {
75 | if (editsPerFiles.isEmpty())
76 | return null;
77 |
78 | pm.beginTask("Searching for references.", editsPerFiles.size());
79 | final CompositeChange changes = new CompositeChange("Update mapper element ID");
80 | int workCount = 0;
81 | for (Entry> editsPerFile : editsPerFiles.entrySet())
82 | {
83 | IFile file = editsPerFile.getKey();
84 | TextChange change = new TextFileChange(file.getName(), file);
85 | TextEdit editRoot = new MultiTextEdit();
86 | change.setEdit(editRoot);
87 | for (ReplaceEdit edit : editsPerFile.getValue())
88 | {
89 | editRoot.addChild(edit);
90 | }
91 | changes.add(change);
92 | pm.worked(++workCount);
93 | }
94 | pm.done();
95 | return changes;
96 | }
97 |
98 | @Override
99 | public String getName()
100 | {
101 | return "Rename MyBatis element";
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/JavaRefactoringPropertyTester.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring;
13 |
14 | import org.eclipse.core.expressions.PropertyTester;
15 | import org.eclipse.core.runtime.CoreException;
16 | import org.eclipse.core.runtime.Status;
17 | import org.eclipse.jdt.core.IJavaElement;
18 | import org.eclipse.jdt.ui.JavaUI;
19 | import org.eclipse.ui.texteditor.ITextEditor;
20 |
21 | import net.harawata.mybatipse.Activator;
22 | import net.harawata.mybatipse.nature.MyBatisNature;
23 |
24 | /**
25 | * @author Iwao AVE!
26 | */
27 | public class JavaRefactoringPropertyTester extends PropertyTester
28 | {
29 | @Override
30 | public boolean test(Object receiver, String property, Object[] args, Object expectedValue)
31 | {
32 | ITextEditor editor = (ITextEditor)receiver;
33 | IJavaElement element = JavaUI.getEditorInputJavaElement(editor.getEditorInput());
34 | if (element != null)
35 | {
36 | if ("isMyBatisProject".equals(property))
37 | {
38 | try
39 | {
40 | return element.getJavaProject().getProject().hasNature(MyBatisNature.NATURE_ID);
41 | }
42 | catch (CoreException e)
43 | {
44 | Activator.log(Status.ERROR, e.getMessage(), e);
45 | }
46 | }
47 | }
48 | return false;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/MapperMethodRenameParticipant.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * ave - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring;
13 |
14 | import java.util.HashMap;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.Map.Entry;
18 |
19 | import org.eclipse.core.resources.IFile;
20 | import org.eclipse.core.runtime.CoreException;
21 | import org.eclipse.core.runtime.IProgressMonitor;
22 | import org.eclipse.core.runtime.NullProgressMonitor;
23 | import org.eclipse.core.runtime.OperationCanceledException;
24 | import org.eclipse.core.runtime.Status;
25 | import org.eclipse.jdt.core.Flags;
26 | import org.eclipse.jdt.core.IAnnotation;
27 | import org.eclipse.jdt.core.IJavaProject;
28 | import org.eclipse.jdt.core.IMethod;
29 | import org.eclipse.jdt.core.IType;
30 | import org.eclipse.jdt.core.JavaModelException;
31 | import org.eclipse.ltk.core.refactoring.Change;
32 | import org.eclipse.ltk.core.refactoring.CompositeChange;
33 | import org.eclipse.ltk.core.refactoring.RefactoringStatus;
34 | import org.eclipse.ltk.core.refactoring.TextChange;
35 | import org.eclipse.ltk.core.refactoring.TextFileChange;
36 | import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
37 | import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
38 | import org.eclipse.text.edits.MultiTextEdit;
39 | import org.eclipse.text.edits.ReplaceEdit;
40 | import org.eclipse.text.edits.TextEdit;
41 |
42 | import net.harawata.mybatipse.Activator;
43 | import net.harawata.mybatipse.refactoring.collector.StatementRenameEditCollector;
44 |
45 | /**
46 | * @author Iwao AVE!
47 | */
48 | public class MapperMethodRenameParticipant extends RenameParticipant
49 | {
50 | private IMethod method;
51 |
52 | @Override
53 | public RefactoringStatus checkConditions(IProgressMonitor monitor,
54 | CheckConditionsContext context) throws OperationCanceledException
55 | {
56 | return new RefactoringStatus();
57 | }
58 |
59 | @Override
60 | public Change createChange(IProgressMonitor monitor)
61 | throws CoreException, OperationCanceledException
62 | {
63 | if (monitor == null)
64 | {
65 | monitor = new NullProgressMonitor();
66 | }
67 | monitor.beginTask("Searching mapper statement changes.", 100);
68 |
69 | try
70 | {
71 | IType type = method.getDeclaringType();
72 | try
73 | {
74 | if (type.isInterface() && (method.getFlags() & Flags.AccDefaultMethod) == 0)
75 | {
76 | final Map> editsPerFiles = new HashMap>();
77 | final IJavaProject project = type.getJavaProject();
78 | final String namespace = type.getFullyQualifiedName();
79 | final String oldId = method.getElementName();
80 | final String newId = getArguments().getNewName();
81 | ElementRenameInfo info = new ElementRenameInfo();
82 | info.setProject(project);
83 | info.setNamespace(namespace);
84 | info.setOldId(oldId);
85 | info.setNewId(newId);
86 | StatementRenameEditCollector collector = new StatementRenameEditCollector(info,
87 | isSelect());
88 | collector.collect(editsPerFiles, monitor);
89 | if (!editsPerFiles.isEmpty())
90 | {
91 | final CompositeChange changes = new CompositeChange("Update mapper statement ID");
92 | for (Entry> editsPerFile : editsPerFiles.entrySet())
93 | {
94 | IFile file = editsPerFile.getKey();
95 | TextChange change = getTextChange(file);
96 | if (change == null)
97 | {
98 | change = new TextFileChange(file.getName(), file);
99 | TextEdit editRoot = new MultiTextEdit();
100 | change.setEdit(editRoot);
101 | changes.add(change);
102 | }
103 | for (ReplaceEdit edit : editsPerFile.getValue())
104 | {
105 | change.getEdit().addChild(edit);
106 | }
107 | }
108 | return changes;
109 | }
110 | }
111 | }
112 | catch (JavaModelException e)
113 | {
114 | Activator.log(Status.ERROR, e.getMessage(), e);
115 | }
116 | }
117 | finally
118 | {
119 | monitor.done();
120 | }
121 | return null;
122 | }
123 |
124 | protected boolean isSelect() throws JavaModelException
125 | {
126 | IAnnotation[] annotations = method.getAnnotations();
127 | for (IAnnotation annotation : annotations)
128 | {
129 | String name = annotation.getElementName();
130 | if ("Select".equals(name) || "SelectProvider".equals(name))
131 | {
132 | return true;
133 | }
134 | }
135 | return false;
136 | }
137 |
138 | @Override
139 | public String getName()
140 | {
141 | return "MapperMethodRenameParticipant";
142 | }
143 |
144 | @Override
145 | protected boolean initialize(Object element)
146 | {
147 | this.method = (IMethod)element;
148 | return true;
149 | }
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/XmlAttrEditRequestor.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Arrays;
16 | import java.util.List;
17 | import java.util.Map;
18 |
19 | import org.eclipse.core.resources.IFile;
20 | import org.eclipse.core.runtime.CoreException;
21 | import org.eclipse.search.core.text.TextSearchMatchAccess;
22 | import org.eclipse.search.core.text.TextSearchRequestor;
23 | import org.eclipse.text.edits.ReplaceEdit;
24 |
25 | /**
26 | * @author Iwao AVE!
27 | */
28 | public class XmlAttrEditRequestor extends TextSearchRequestor
29 | {
30 | private final List attrNames;
31 |
32 | private final String newValue;
33 |
34 | private final Map> editsPerFiles;
35 |
36 | public XmlAttrEditRequestor(
37 | String attrName,
38 | String newValue,
39 | Map> editsPerFiles)
40 | {
41 | this(Arrays.asList(attrName), newValue, editsPerFiles);
42 | }
43 |
44 | public XmlAttrEditRequestor(
45 | List attrNames,
46 | String newValue,
47 | Map> editsPerFiles)
48 | {
49 | super();
50 | this.attrNames = attrNames;
51 | this.newValue = newValue;
52 | this.editsPerFiles = editsPerFiles;
53 | }
54 |
55 | @Override
56 | public boolean acceptPatternMatch(TextSearchMatchAccess matchAccess) throws CoreException
57 | {
58 | int matchOffset = matchAccess.getMatchOffset();
59 | if (isActualMatch(matchAccess, matchOffset))
60 | {
61 | List edits = getEdits(matchAccess.getFile());
62 | edits.add(
63 | new ReplaceEdit(matchAccess.getMatchOffset(), matchAccess.getMatchLength(), newValue));
64 | }
65 | return true;
66 | }
67 |
68 | protected boolean isActualMatch(TextSearchMatchAccess matchAccess, int matchOffset)
69 | {
70 | if (!newValue.startsWith("\"") && (",\" "
71 | .indexOf(matchAccess.getFileContentChar(matchOffset + matchAccess.getMatchLength())) == -1
72 | || ",\" ".indexOf(matchAccess.getFileContentChar(matchOffset - 1)) == -1))
73 | return false;
74 |
75 | StringBuilder buffer = new StringBuilder();
76 | boolean nameRegion = false;
77 | for (int i = 1; i < matchOffset; i++)
78 | {
79 | char c = matchAccess.getFileContentChar(matchOffset - i);
80 | if (!nameRegion)
81 | {
82 | if (c == '=')
83 | nameRegion = true;
84 | }
85 | else if (Character.isWhitespace(c) && buffer.length() > 0)
86 | {
87 | break;
88 | }
89 | else
90 | {
91 | buffer.insert(0, c);
92 | }
93 | }
94 | return attrNames.contains(buffer.toString());
95 | }
96 |
97 | private List getEdits(final IFile mapperXml)
98 | {
99 | List edits = editsPerFiles.get(mapperXml);
100 | if (edits == null)
101 | {
102 | edits = new ArrayList();
103 | editsPerFiles.put(mapperXml, edits);
104 | }
105 | return edits;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/collector/RenameEditCollector.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.collector;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.Map;
17 |
18 | import org.eclipse.core.resources.IFile;
19 | import org.eclipse.core.runtime.IProgressMonitor;
20 | import org.eclipse.ltk.core.refactoring.RefactoringStatus;
21 | import org.eclipse.text.edits.ReplaceEdit;
22 |
23 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
24 |
25 | /**
26 | * @author Iwao AVE!
27 | */
28 | public abstract class RenameEditCollector
29 | {
30 | protected final ElementRenameInfo info;
31 |
32 | protected Map> editsPerFiles;
33 |
34 | protected IProgressMonitor monitor;
35 |
36 | public RenameEditCollector(ElementRenameInfo info)
37 | {
38 | super();
39 | this.info = info;
40 | }
41 |
42 | protected List getEdits(final IFile file)
43 | {
44 | List edits = editsPerFiles.get(file);
45 | if (edits == null)
46 | {
47 | edits = new ArrayList();
48 | editsPerFiles.put(file, edits);
49 | }
50 | return edits;
51 | }
52 |
53 | public abstract RefactoringStatus collect(Map> editsPerFiles,
54 | IProgressMonitor monitor);
55 | }
56 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/collector/SqlRenameEditCollector.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.collector;
13 |
14 | import java.util.List;
15 | import java.util.Map;
16 | import java.util.regex.Pattern;
17 |
18 | import javax.xml.xpath.XPathExpressionException;
19 |
20 | import org.eclipse.core.resources.IFile;
21 | import org.eclipse.core.resources.IResource;
22 | import org.eclipse.core.runtime.IProgressMonitor;
23 | import org.eclipse.core.runtime.Status;
24 | import org.eclipse.ltk.core.refactoring.RefactoringStatus;
25 | import org.eclipse.search.core.text.TextSearchEngine;
26 | import org.eclipse.search.ui.text.FileTextSearchScope;
27 | import org.eclipse.text.edits.ReplaceEdit;
28 | import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
29 | import org.eclipse.wst.xml.core.internal.document.AttrImpl;
30 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
31 | import org.w3c.dom.Node;
32 | import org.w3c.dom.NodeList;
33 |
34 | import net.harawata.mybatipse.Activator;
35 | import net.harawata.mybatipse.mybatis.MapperNamespaceCache;
36 | import net.harawata.mybatipse.mybatis.MybatipseXmlUtil;
37 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
38 | import net.harawata.mybatipse.refactoring.XmlAttrEditRequestor;
39 | import net.harawata.mybatipse.util.XpathUtil;
40 |
41 | /**
42 | * @author Iwao AVE!
43 | */
44 | @SuppressWarnings("restriction")
45 | public class SqlRenameEditCollector extends RenameEditCollector
46 | {
47 | public SqlRenameEditCollector(ElementRenameInfo info)
48 | {
49 | super(info);
50 | }
51 |
52 | @Override
53 | public RefactoringStatus collect(Map> editsPerFiles,
54 | IProgressMonitor monitor)
55 | {
56 | this.editsPerFiles = editsPerFiles;
57 | this.monitor = monitor;
58 | RefactoringStatus result = new RefactoringStatus();
59 | try
60 | {
61 | monitor.beginTask("Updating sql ID", 100);
62 | editLocal(result);
63 | monitor.worked(30);
64 | editFullyQualifiedRef(result);
65 | }
66 | catch (XPathExpressionException e)
67 | {
68 | Activator.log(Status.ERROR, e.getMessage(), e);
69 | }
70 | return result;
71 | }
72 |
73 | private void editLocal(RefactoringStatus result) throws XPathExpressionException
74 | {
75 | for (IFile sourceXmlFile : MapperNamespaceCache.getInstance()
76 | .get(info.getProject(), info.getNamespace(), null))
77 | {
78 | IDOMDocument sourceXmlDoc = MybatipseXmlUtil.getMapperDocument(sourceXmlFile);
79 | if (sourceXmlDoc == null)
80 | return;
81 | List edits = getEdits(sourceXmlFile);
82 | // Source element
83 | Node node = XpathUtil.xpathNode(sourceXmlDoc, "//sql[@id='" + info.getOldId() + "']/@id");
84 | if (node instanceof AttrImpl)
85 | {
86 | AttrImpl attrImpl = (AttrImpl)node;
87 | edits.add(new ReplaceEdit(attrImpl.getValueRegionStartOffset(),
88 | attrImpl.getValueRegion().getTextLength(), "\"" + info.getNewId() + "\""));
89 | }
90 | // Local elements
91 | NodeList references = XpathUtil.xpathNodes(sourceXmlDoc,
92 | "//*[@refid='" + info.getOldId() + "']/@refid");
93 | for (int i = 0; i < references.getLength(); i++)
94 | {
95 | AttrImpl attrImpl = (AttrImpl)references.item(i);
96 | ITextRegion valueRegion = attrImpl.getValueRegion();
97 | edits.add(new ReplaceEdit(attrImpl.getValueRegionStartOffset(),
98 | valueRegion.getTextLength(), "\"" + info.getNewId() + "\""));
99 | }
100 | }
101 | }
102 |
103 | private void editFullyQualifiedRef(RefactoringStatus result)
104 | {
105 | String[] fileNamePatterns = new String[]{
106 | "*.xml"
107 | };
108 | FileTextSearchScope scope = FileTextSearchScope.newSearchScope(new IResource[]{
109 | info.getProject().getProject()
110 | }, fileNamePatterns, false);
111 | XmlAttrEditRequestor requestor = new XmlAttrEditRequestor("refid",
112 | "\"" + info.getNamespace() + "." + info.getNewId() + "\"", editsPerFiles);
113 | Pattern pattern = Pattern
114 | .compile("\"" + info.getNamespace() + "." + info.getOldId() + "\"");
115 | TextSearchEngine.create().search(scope, requestor, pattern, monitor);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/collector/StatementRenameEditCollector.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.collector;
13 |
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | import javax.xml.xpath.XPathExpressionException;
18 |
19 | import org.eclipse.core.resources.IFile;
20 | import org.eclipse.core.runtime.CoreException;
21 | import org.eclipse.core.runtime.IProgressMonitor;
22 | import org.eclipse.core.runtime.Status;
23 | import org.eclipse.jdt.core.IAnnotation;
24 | import org.eclipse.jdt.core.IJavaElement;
25 | import org.eclipse.jdt.core.IMemberValuePair;
26 | import org.eclipse.jdt.core.IMethod;
27 | import org.eclipse.jdt.core.JavaModelException;
28 | import org.eclipse.jdt.core.search.IJavaSearchConstants;
29 | import org.eclipse.jdt.core.search.IJavaSearchScope;
30 | import org.eclipse.jdt.core.search.SearchEngine;
31 | import org.eclipse.jdt.core.search.SearchMatch;
32 | import org.eclipse.jdt.core.search.SearchParticipant;
33 | import org.eclipse.jdt.core.search.SearchPattern;
34 | import org.eclipse.jdt.core.search.SearchRequestor;
35 | import org.eclipse.ltk.core.refactoring.RefactoringStatus;
36 | import org.eclipse.text.edits.ReplaceEdit;
37 | import org.eclipse.wst.xml.core.internal.document.AttrImpl;
38 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
39 | import org.w3c.dom.Node;
40 | import org.w3c.dom.NodeList;
41 |
42 | import net.harawata.mybatipse.Activator;
43 | import net.harawata.mybatipse.MybatipseConstants;
44 | import net.harawata.mybatipse.mybatis.MapperNamespaceCache;
45 | import net.harawata.mybatipse.mybatis.MybatipseXmlUtil;
46 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
47 | import net.harawata.mybatipse.util.XpathUtil;
48 |
49 | /**
50 | * @author Iwao AVE!
51 | */
52 | @SuppressWarnings("restriction")
53 | public class StatementRenameEditCollector extends RenameEditCollector
54 | {
55 | private boolean isSelect;
56 |
57 | private final String fullyQualifiedOldId;
58 |
59 | private final String quotedFullyQualifiedOldId;
60 |
61 | private final String quotedOldId;
62 |
63 | private final String fullyQualifiedNewId;
64 |
65 | public StatementRenameEditCollector(ElementRenameInfo info, boolean isSelect)
66 | {
67 | super(info);
68 | this.isSelect = isSelect;
69 | quotedOldId = "\"" + info.getOldId() + "\"";
70 | fullyQualifiedOldId = info.getNamespace() + "." + info.getOldId();
71 | quotedFullyQualifiedOldId = "\"" + fullyQualifiedOldId + "\"";
72 | fullyQualifiedNewId = info.getNamespace() + "." + info.getNewId();
73 | }
74 |
75 | @Override
76 | public RefactoringStatus collect(Map> editsPerFiles,
77 | IProgressMonitor monitor)
78 | {
79 | this.editsPerFiles = editsPerFiles;
80 | this.monitor = monitor;
81 | RefactoringStatus result = new RefactoringStatus();
82 | try
83 | {
84 | monitor.beginTask("Updating statement ID", 100);
85 | editXmlLocal(result);
86 | monitor.worked(30);
87 | if (isSelect)
88 | editJavaReferences(result);
89 | }
90 | catch (XPathExpressionException e)
91 | {
92 | Activator.log(Status.ERROR, e.getMessage(), e);
93 | }
94 | return result;
95 | }
96 |
97 | protected void editXmlLocal(RefactoringStatus result) throws XPathExpressionException
98 | {
99 | for (IFile mapperXml : MapperNamespaceCache.getInstance()
100 | .get(info.getProject(), info.getNamespace(), null))
101 | {
102 | final IDOMDocument mapperDocument = MybatipseXmlUtil.getMapperDocument(mapperXml);
103 | if (mapperDocument == null)
104 | return;
105 | List edits = getEdits(mapperXml);
106 | Node node = XpathUtil.xpathNode(mapperDocument,
107 | "//select[@id='" + info.getOldId() + "']/@id|//insert[@id='" + info.getOldId()
108 | + "']/@id|//update[@id='" + info.getOldId() + "']/@id|//delete[@id='"
109 | + info.getOldId() + "']/@id");
110 | if (node instanceof AttrImpl)
111 | {
112 | AttrImpl attrImpl = (AttrImpl)node;
113 | isSelect |= "select".equals(attrImpl.getOwnerElement().getNodeName());
114 | edits.add(new ReplaceEdit(attrImpl.getValueRegionStartOffset(),
115 | attrImpl.getValueRegion().getTextLength(), "\"" + info.getNewId() + "\""));
116 | }
117 | if (isSelect)
118 | {
119 | // Local references in XML mapper
120 | NodeList attrNodes = XpathUtil.xpathNodes(mapperDocument,
121 | "//*[@select='" + info.getOldId() + "']/@select");
122 | for (int i = 0; i < attrNodes.getLength(); i++)
123 | {
124 | AttrImpl attrImpl = (AttrImpl)attrNodes.item(i);
125 | edits.add(new ReplaceEdit(attrImpl.getValueRegionStartOffset(),
126 | attrImpl.getValueRegion().getTextLength(), "\"" + info.getNewId() + "\""));
127 | }
128 | }
129 | }
130 | }
131 |
132 | protected void editJavaReferences(RefactoringStatus result)
133 | {
134 | // Awful...any better way?
135 | editAnnotation(MybatipseConstants.ANNOTATION_ONE);
136 | editAnnotation(MybatipseConstants.ANNOTATION_MANY);
137 | }
138 |
139 | protected void editAnnotation(String annotationType)
140 | {
141 | SearchPattern pattern = SearchPattern.createPattern(annotationType,
142 | IJavaSearchConstants.ANNOTATION_TYPE, IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE,
143 | SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
144 | SearchParticipant[] participants = {
145 | SearchEngine.getDefaultSearchParticipant()
146 | };
147 | IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{
148 | info.getProject()
149 | });
150 | SearchRequestor requestor = new SearchRequestor()
151 | {
152 | @Override
153 | public void acceptSearchMatch(SearchMatch match) throws CoreException
154 | {
155 | Object element = match.getElement();
156 | if (element instanceof IMethod)
157 | {
158 | IMethod method = (IMethod)element;
159 | String mapperFqn = method.getDeclaringType().getFullyQualifiedName();
160 | for (IAnnotation anno : method.getAnnotations())
161 | {
162 | if ("Results".equals(anno.getElementName()))
163 | {
164 | for (IMemberValuePair resultsParam : anno.getMemberValuePairs())
165 | {
166 | if ("value".equals(resultsParam.getMemberName()))
167 | {
168 | Object resultsValue = resultsParam.getValue();
169 | if (resultsValue instanceof Object[])
170 | {
171 | for (Object resultAnno : (Object[])resultsValue)
172 | {
173 | parseResultAnnotation((IAnnotation)resultAnno, mapperFqn,
174 | (IFile)match.getResource());
175 | }
176 | }
177 | else
178 | {
179 | parseResultAnnotation((IAnnotation)resultsValue, mapperFqn,
180 | (IFile)match.getResource());
181 | }
182 | break;
183 | }
184 | }
185 | break;
186 | }
187 | }
188 | }
189 | }
190 |
191 | protected void parseResultAnnotation(IAnnotation resultAnno, String mapperFqn, IFile file)
192 | throws JavaModelException
193 | {
194 | for (IMemberValuePair resultParam : resultAnno.getMemberValuePairs())
195 | {
196 | String name = resultParam.getMemberName();
197 | if ("one".equals(name) || "many".equals(name))
198 | {
199 | IAnnotation annotation = (IAnnotation)resultParam.getValue();
200 | int oldIdIdx = -1;
201 | int oldIdLength = info.getOldId().length();
202 | String newId = info.getNewId();
203 | String source = annotation.getSource();
204 | if (info.getNamespace().equals(mapperFqn))
205 | {
206 | oldIdIdx = source.indexOf(quotedOldId);
207 | }
208 | if (oldIdIdx == -1)
209 | {
210 | oldIdIdx = source.indexOf(quotedFullyQualifiedOldId);
211 | oldIdLength = fullyQualifiedOldId.length();
212 | newId = fullyQualifiedNewId;
213 | }
214 | if (oldIdIdx > -1)
215 | {
216 | int offset = annotation.getSourceRange().getOffset() + oldIdIdx + 1;
217 | List edits = getEdits(file);
218 | edits.add(new ReplaceEdit(offset, oldIdLength, newId));
219 | }
220 | break;
221 | }
222 | }
223 | }
224 | };
225 |
226 | try
227 | {
228 | new SearchEngine().search(pattern, participants, scope, requestor, monitor);
229 | }
230 | catch (CoreException e)
231 | {
232 | Activator.log(Status.ERROR, e.getMessage(), e);
233 | }
234 | }
235 |
236 | }
237 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/handler/ElementRenameHandler.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.handler;
13 |
14 | import org.eclipse.core.commands.AbstractHandler;
15 | import org.eclipse.core.runtime.CoreException;
16 | import org.eclipse.core.runtime.Status;
17 | import org.eclipse.jdt.core.IMethod;
18 | import org.eclipse.jdt.ui.refactoring.RenameSupport;
19 | import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
20 | import org.eclipse.swt.widgets.Shell;
21 | import org.eclipse.ui.IEditorPart;
22 | import org.eclipse.ui.IWorkbenchWindow;
23 | import org.eclipse.ui.PlatformUI;
24 |
25 | import net.harawata.mybatipse.Activator;
26 | import net.harawata.mybatipse.mybatis.JavaMapperUtil;
27 | import net.harawata.mybatipse.mybatis.JavaMapperUtil.MethodNameMatcher;
28 | import net.harawata.mybatipse.mybatis.JavaMapperUtil.SingleMethodStore;
29 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
30 | import net.harawata.mybatipse.refactoring.ElementRenameRefactoring;
31 | import net.harawata.mybatipse.refactoring.wizard.ElementRenameWizard;
32 |
33 | /**
34 | * @author Iwao AVE!
35 | */
36 | public abstract class ElementRenameHandler extends AbstractHandler
37 | {
38 | protected IWorkbenchWindow workbenchWindow;
39 |
40 | protected IEditorPart editor;
41 |
42 | protected void invokeJdtRename(IMethod method)
43 | {
44 | try
45 | {
46 | RenameSupport renameSupport = RenameSupport.create(method, null,
47 | RenameSupport.UPDATE_REFERENCES);
48 | renameSupport.openDialog(workbenchWindow.getShell());
49 | }
50 | catch (CoreException e)
51 | {
52 | Activator.log(Status.ERROR, e.getMessage(), e);
53 | }
54 | }
55 |
56 | protected IMethod findMapperMethod(ElementRenameInfo refactoringInfo)
57 | {
58 | SingleMethodStore methodStore = new SingleMethodStore();
59 | JavaMapperUtil.findMapperMethod(methodStore, refactoringInfo.getProject(),
60 | refactoringInfo.getNamespace(), new MethodNameMatcher(refactoringInfo.getOldId(), true));
61 | IMethod method = methodStore.getMethod();
62 | return method;
63 | }
64 |
65 | protected void runRefactoringWizard(ElementRenameInfo refactoringInfo,
66 | ElementRenameRefactoring refactoring)
67 | {
68 | ElementRenameWizard wizard = new ElementRenameWizard(refactoring, refactoringInfo);
69 | RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
70 | try
71 | {
72 | String titleForFailedChecks = ""; //$NON-NLS-1$
73 | op.run(getShell(), titleForFailedChecks);
74 | }
75 | catch (final InterruptedException irex)
76 | {
77 | // operation was cancelled
78 | }
79 | }
80 |
81 | protected Shell getShell()
82 | {
83 | Shell result = null;
84 | if (editor != null)
85 | {
86 | result = editor.getSite().getShell();
87 | }
88 | else
89 | {
90 | result = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
91 | }
92 | return result;
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/handler/XmlElementRenameHandler.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.handler;
13 |
14 | import org.eclipse.core.commands.ExecutionEvent;
15 | import org.eclipse.core.commands.ExecutionException;
16 | import org.eclipse.jdt.core.IMethod;
17 | import org.eclipse.jface.text.IDocument;
18 | import org.eclipse.jface.text.ITextSelection;
19 | import org.eclipse.jface.viewers.ISelection;
20 | import org.eclipse.jface.viewers.IStructuredSelection;
21 | import org.eclipse.ui.IWorkbenchPage;
22 | import org.eclipse.ui.handlers.HandlerUtil;
23 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
24 | import org.w3c.dom.Element;
25 |
26 | import net.harawata.mybatipse.mybatis.MybatipseXmlUtil;
27 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
28 | import net.harawata.mybatipse.refactoring.ElementRenameRefactoring;
29 | import net.harawata.mybatipse.refactoring.collector.ResultMapRenameEditCollector;
30 | import net.harawata.mybatipse.refactoring.collector.SqlRenameEditCollector;
31 | import net.harawata.mybatipse.refactoring.collector.StatementRenameEditCollector;
32 |
33 | /**
34 | * @author Iwao AVE!
35 | */
36 | @SuppressWarnings("restriction")
37 | public class XmlElementRenameHandler extends ElementRenameHandler
38 | {
39 | @Override
40 | public Object execute(ExecutionEvent event) throws ExecutionException
41 | {
42 | workbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event);
43 | if (workbenchWindow == null)
44 | return null;
45 |
46 | IWorkbenchPage activePage = workbenchWindow.getActivePage();
47 | if (activePage == null)
48 | return null;
49 |
50 | editor = HandlerUtil.getActiveEditor(event);
51 | if (editor == null)
52 | return null;
53 |
54 | // HandlerUtil.getCurrentSelection(event) does not return
55 | // the latest 'selection' when the cursor is moved.
56 | ISelection selection = activePage.getSelection();
57 | if (selection != null && selection instanceof IStructuredSelection
58 | && selection instanceof ITextSelection)
59 | {
60 | Object selected = ((IStructuredSelection)selection).getFirstElement();
61 | if (selected instanceof IDOMAttr)
62 | {
63 | IDocument document = editor.getAdapter(IDocument.class);
64 | final IDOMAttr attr = (IDOMAttr)selected;
65 | final String attrName = attr.getName();
66 | final Element tag = attr.getOwnerElement();
67 | if ("select".equals(attrName) || ("id".equals(attrName)
68 | && MybatipseXmlUtil.findEnclosingStatementNode(tag) != null))
69 | {
70 | renameStatementId(document, attr);
71 | }
72 | else if ("refid".equals(attrName)
73 | || ("id".equals(attrName) && "sql".equals(tag.getTagName())))
74 | {
75 | renameSqlId(document, attr);
76 | }
77 | else if ("resultMap".equals(attrName)
78 | || ("id".equals(attrName) && "resultMap".equals(tag.getTagName())))
79 | {
80 | int offset = ((ITextSelection)selection).getOffset();
81 | renameResultMapId(document, attr, offset);
82 | // OUT param's resultMap option is not supported
83 | }
84 | }
85 | }
86 | return null;
87 | }
88 |
89 | protected void renameResultMapId(IDocument document, final IDOMAttr attr, int offset)
90 | {
91 | String id = attr.getValue();
92 | if (id.indexOf(',') > -1)
93 | {
94 | // multiple result maps. get the one that has the cursor.
95 | String valueRegionText = attr.getValueRegionText();
96 | int selectionOffset = offset - attr.getValueRegionStartOffset();
97 | int valueOffset = valueRegionText.indexOf(id);
98 | int start = valueRegionText.lastIndexOf(',', selectionOffset - 1);
99 | start = start == -1 ? valueOffset : start + 1;
100 | int end = valueRegionText.indexOf(',', selectionOffset);
101 | end = end == -1 ? valueOffset + id.length() : end;
102 | id = valueRegionText.substring(start, end).trim();
103 | }
104 | ElementRenameInfo refactoringInfo = createRefactoringInfo(document, attr, id);
105 | ElementRenameRefactoring refactoring = new ElementRenameRefactoring(
106 | new ResultMapRenameEditCollector(refactoringInfo));
107 | runRefactoringWizard(refactoringInfo, refactoring);
108 | }
109 |
110 | protected void renameSqlId(IDocument document, final IDOMAttr attr)
111 | {
112 | final String id = attr.getValue();
113 | ElementRenameInfo refactoringInfo = createRefactoringInfo(document, attr, id);
114 | ElementRenameRefactoring refactoring = new ElementRenameRefactoring(
115 | new SqlRenameEditCollector(refactoringInfo));
116 | runRefactoringWizard(refactoringInfo, refactoring);
117 | }
118 |
119 | protected void renameStatementId(IDocument document, final IDOMAttr attr)
120 | {
121 | String id = attr.getValue();
122 | ElementRenameInfo refactoringInfo = createRefactoringInfo(document, attr, id);
123 | IMethod method = findMapperMethod(refactoringInfo);
124 | if (method == null)
125 | {
126 | ElementRenameRefactoring refactoring = new ElementRenameRefactoring(
127 | new StatementRenameEditCollector(refactoringInfo, false));
128 | runRefactoringWizard(refactoringInfo, refactoring);
129 | }
130 | else
131 | {
132 | invokeJdtRename(method);
133 | }
134 | }
135 |
136 | protected ElementRenameInfo createRefactoringInfo(IDocument document, final IDOMAttr attr,
137 | String id)
138 | {
139 | String namespace;
140 | String oldId;
141 | int namespaceEnd = id.lastIndexOf('.');
142 | if (namespaceEnd > -1)
143 | {
144 | oldId = id.substring(namespaceEnd + 1);
145 | namespace = id.substring(0, namespaceEnd);
146 | }
147 | else
148 | {
149 | oldId = id;
150 | namespace = MybatipseXmlUtil.getNamespace(attr.getOwnerDocument());
151 | }
152 | ElementRenameInfo refactoringInfo = new ElementRenameInfo();
153 | refactoringInfo.setOldId(oldId);
154 | refactoringInfo.setNamespace(namespace);
155 | refactoringInfo.setProject(MybatipseXmlUtil.getJavaProject(document));
156 | return refactoringInfo;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/wizard/ElementRenameWizard.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.wizard;
13 |
14 | import org.eclipse.ltk.core.refactoring.Refactoring;
15 | import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
16 |
17 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
18 |
19 | /**
20 | * @author Iwao AVE!
21 | */
22 | public class ElementRenameWizard extends RefactoringWizard
23 | {
24 | private final ElementRenameInfo info;
25 |
26 | public ElementRenameWizard(Refactoring refactoring, ElementRenameInfo info)
27 | {
28 | super(refactoring, DIALOG_BASED_USER_INTERFACE);
29 | this.info = info;
30 | }
31 |
32 | @Override
33 | protected void addUserInputPages()
34 | {
35 | setDefaultPageTitle(getRefactoring().getName());
36 | addPage(new ElementRenameWizardPage(info));
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/refactoring/wizard/ElementRenameWizardPage.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.refactoring.wizard;
13 |
14 | import org.eclipse.jface.dialogs.Dialog;
15 | import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
16 | import org.eclipse.swt.SWT;
17 | import org.eclipse.swt.events.KeyAdapter;
18 | import org.eclipse.swt.events.KeyEvent;
19 | import org.eclipse.swt.layout.GridData;
20 | import org.eclipse.swt.layout.GridLayout;
21 | import org.eclipse.swt.widgets.Composite;
22 | import org.eclipse.swt.widgets.Label;
23 | import org.eclipse.swt.widgets.Text;
24 |
25 | import net.harawata.mybatipse.refactoring.ElementRenameInfo;
26 |
27 | /**
28 | * @author Iwao AVE!
29 | */
30 | public class ElementRenameWizardPage extends UserInputWizardPage
31 | {
32 | private final ElementRenameInfo info;
33 |
34 | private Text txtNewName;
35 |
36 | public ElementRenameWizardPage(ElementRenameInfo info)
37 | {
38 | super(ElementRenameWizardPage.class.getName());
39 | this.info = info;
40 | }
41 |
42 | @Override
43 | public void createControl(Composite parent)
44 | {
45 | Composite rootComposite = createRootComposite(parent);
46 | setControl(rootComposite);
47 |
48 | createLblNewName(rootComposite);
49 | createTxtNewName(rootComposite);
50 |
51 | validate();
52 | }
53 |
54 | private Composite createRootComposite(final Composite parent)
55 | {
56 | Composite result = new Composite(parent, SWT.NONE);
57 | GridLayout gridLayout = new GridLayout(2, false);
58 | gridLayout.marginWidth = 10;
59 | gridLayout.marginHeight = 10;
60 | result.setLayout(gridLayout);
61 | initializeDialogUnits(result);
62 | Dialog.applyDialogFont(result);
63 | return result;
64 | }
65 |
66 | private void createLblNewName(final Composite composite)
67 | {
68 | Label lblNewName = new Label(composite, SWT.NONE);
69 | lblNewName.setText("New ID");
70 | }
71 |
72 | private void createTxtNewName(Composite composite)
73 | {
74 | txtNewName = new Text(composite, SWT.BORDER);
75 | txtNewName.setText(info.getOldId());
76 | txtNewName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
77 | txtNewName.selectAll();
78 | txtNewName.addKeyListener(new KeyAdapter()
79 | {
80 | public void keyReleased(final KeyEvent e)
81 | {
82 | info.setNewId(txtNewName.getText());
83 | validate();
84 | }
85 | });
86 | }
87 |
88 | private void validate()
89 | {
90 | String txt = txtNewName.getText();
91 | setPageComplete(txt.length() > 0 && !txt.equals(info.getOldId()));
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/util/NameUtil.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.util;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Collections;
16 | import java.util.List;
17 |
18 | import org.eclipse.core.runtime.Status;
19 | import org.eclipse.jdt.core.IJavaProject;
20 | import org.eclipse.jdt.core.IType;
21 | import org.eclipse.jdt.core.JavaModelException;
22 |
23 | import net.harawata.mybatipse.Activator;
24 | import net.harawata.mybatipse.bean.SupertypeHierarchyCache;
25 |
26 | /**
27 | * @author Iwao AVE!
28 | */
29 | public class NameUtil
30 | {
31 | /**
32 | * @param packageName
33 | * @param simpleTypeName
34 | * @param enclosingTypeNames
35 | * @param useDollarForInnerClassSeparator Simply put, MyBatis uses '$' and Eclipse uses '.'.
36 | * In other words, pass true
for auto-completion and false
37 | * for validation.
38 | * @return
39 | */
40 | public static String buildQualifiedName(char[] packageName, char[] simpleTypeName,
41 | char[][] enclosingTypeNames, boolean useDollarForInnerClassSeparator)
42 | {
43 | final char innerClassSeparator = useDollarForInnerClassSeparator ? '$' : '.';
44 | StringBuilder typeFqn = new StringBuilder().append(packageName).append('.');
45 | for (char[] enclosingTypeName : enclosingTypeNames)
46 | {
47 | typeFqn.append(enclosingTypeName).append(innerClassSeparator);
48 | }
49 | typeFqn.append(simpleTypeName).toString();
50 | return typeFqn.toString();
51 | }
52 |
53 | public static boolean isArray(String src)
54 | {
55 | return src.endsWith("[]");
56 | }
57 |
58 | public static String extractArrayComponentType(String src)
59 | {
60 | if (!isArray(src))
61 | {
62 | return src;
63 | }
64 | return src.substring(0, src.length() - 1);
65 | }
66 |
67 | public static String manageableReturnType(IJavaProject project, String declaredReturnType)
68 | {
69 | if ("void".equals(declaredReturnType))
70 | {
71 | return null;
72 | }
73 | else if (declaredReturnType.indexOf('<') == -1)
74 | {
75 | return declaredReturnType;
76 | }
77 | else
78 | {
79 | try
80 | {
81 | IType rawType = project.findType(NameUtil.stripTypeArguments(declaredReturnType));
82 | if (SupertypeHierarchyCache.getInstance().isCollection(rawType))
83 | {
84 | List typeParams = NameUtil.extractTypeParams(declaredReturnType);
85 | if (typeParams.size() == 1)
86 | {
87 | return typeParams.get(0);
88 | }
89 | }
90 | }
91 | catch (JavaModelException e)
92 | {
93 | Activator.log(Status.ERROR, e.getMessage(), e);
94 | }
95 | }
96 | return null;
97 | }
98 |
99 | public static String stripTypeArguments(String src)
100 | {
101 | int idx = src.indexOf('<');
102 | return idx == -1 ? src : src.substring(0, idx);
103 | }
104 |
105 | public static List extractTypeParams(String src)
106 | {
107 | int paramPartStart = src.indexOf('<');
108 | int paramPartEnd = src.lastIndexOf('>');
109 | if (paramPartStart == -1 || paramPartEnd == -1 || paramPartEnd - paramPartStart < 2)
110 | return Collections.emptyList();
111 |
112 | List result = new ArrayList();
113 | int nestedParamLevel = 0;
114 | int markStart = paramPartStart + 1;
115 | for (int i = paramPartStart + 1; i < paramPartEnd; i++)
116 | {
117 | char c = src.charAt(i);
118 | if (nestedParamLevel == 0 && c == ',')
119 | {
120 | result.add(src.substring(markStart, i));
121 | markStart = i + 1;
122 | }
123 | else if (c == '<')
124 | {
125 | nestedParamLevel++;
126 | }
127 | else if (c == '>')
128 | {
129 | nestedParamLevel--;
130 | }
131 | }
132 | if (markStart < paramPartEnd)
133 | result.add(src.substring(markStart, paramPartEnd));
134 | return result;
135 | }
136 |
137 | public static String resolveTypeParam(List actualTypeParams, List typeParams,
138 | String typeParam)
139 | {
140 | int typeParamIdx = typeParams.indexOf(typeParam);
141 | return typeParamIdx == -1 || actualTypeParams.isEmpty() ? typeParam
142 | : actualTypeParams.get(typeParamIdx);
143 | }
144 |
145 | private NameUtil()
146 | {
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/util/XpathUtil.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2014 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.util;
13 |
14 | import javax.xml.namespace.NamespaceContext;
15 | import javax.xml.namespace.QName;
16 | import javax.xml.xpath.XPath;
17 | import javax.xml.xpath.XPathConstants;
18 | import javax.xml.xpath.XPathExpressionException;
19 | import javax.xml.xpath.XPathFactory;
20 |
21 | import org.w3c.dom.Node;
22 | import org.w3c.dom.NodeList;
23 |
24 | /**
25 | * @author Iwao AVE!
26 | */
27 | public class XpathUtil
28 | {
29 | private static final ThreadLocal XPATH_FACTORY = new ThreadLocal()
30 | {
31 | @Override
32 | protected XPathFactory initialValue()
33 | {
34 | return XPathFactory.newInstance();
35 | }
36 | };
37 |
38 | public static boolean xpathBool(Node node, String expression) throws XPathExpressionException
39 | {
40 | return ((Boolean)evaluateXpath(expression, node, XPathConstants.BOOLEAN, null))
41 | .booleanValue();
42 | }
43 |
44 | public static String xpathString(Node node, String expression) throws XPathExpressionException
45 | {
46 | return (String)evaluateXpath(expression, node, XPathConstants.STRING, null);
47 | }
48 |
49 | public static Node xpathNode(Node node, String expression) throws XPathExpressionException
50 | {
51 | return (Node)evaluateXpath(expression, node, XPathConstants.NODE, null);
52 | }
53 |
54 | public static NodeList xpathNodes(Node node, String expression)
55 | throws XPathExpressionException
56 | {
57 | return xpathNodes(node, expression, null);
58 | }
59 |
60 | public static NodeList xpathNodes(Node node, String expression, NamespaceContext nsContext)
61 | throws XPathExpressionException
62 | {
63 | return (NodeList)evaluateXpath(expression, node, XPathConstants.NODESET, nsContext);
64 | }
65 |
66 | public static Object evaluateXpath(String expression, Object node, QName returnType,
67 | NamespaceContext nsContext) throws XPathExpressionException
68 | {
69 | XPath xpath = XPATH_FACTORY.get().newXPath();
70 | if (nsContext != null)
71 | {
72 | xpath.setNamespaceContext(nsContext);
73 | }
74 | return xpath.evaluate(expression, node, returnType);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/wizard/NewXmlMapperWizard.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.wizard;
13 |
14 | import java.io.IOException;
15 |
16 | import org.eclipse.core.resources.IFile;
17 | import org.eclipse.core.resources.IProject;
18 | import org.eclipse.core.runtime.CoreException;
19 | import org.eclipse.core.runtime.IPath;
20 | import org.eclipse.core.runtime.Status;
21 | import org.eclipse.jdt.core.IClasspathEntry;
22 | import org.eclipse.jdt.core.IJavaProject;
23 | import org.eclipse.jdt.core.JavaCore;
24 | import org.eclipse.jdt.core.JavaModelException;
25 | import org.eclipse.jface.viewers.IStructuredSelection;
26 | import org.eclipse.jface.wizard.Wizard;
27 | import org.eclipse.ui.INewWizard;
28 | import org.eclipse.ui.IWorkbench;
29 | import org.eclipse.ui.PartInitException;
30 | import org.eclipse.ui.ide.IDE;
31 | import org.eclipse.wst.sse.core.StructuredModelManager;
32 | import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
33 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
34 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
35 | import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
36 | import org.w3c.dom.Element;
37 |
38 | import net.harawata.mybatipse.Activator;
39 |
40 | /**
41 | * @author Iwao AVE!
42 | */
43 | @SuppressWarnings("restriction")
44 | public class NewXmlMapperWizard extends Wizard implements INewWizard
45 | {
46 | private IStructuredSelection selection;
47 |
48 | private IWorkbench workbench;
49 |
50 | private NewXmlMapperWizardPage wizardPage;
51 |
52 | public NewXmlMapperWizard()
53 | {
54 | setWindowTitle("New MyBatis XML Mapper");
55 | }
56 |
57 | @Override
58 | public void addPages()
59 | {
60 | wizardPage = new NewXmlMapperWizardPage(selection);
61 | addPage(wizardPage);
62 | }
63 |
64 | @Override
65 | public void init(IWorkbench workbench, IStructuredSelection selection)
66 | {
67 | this.workbench = workbench;
68 | this.selection = selection;
69 | }
70 |
71 | @Override
72 | public boolean performFinish()
73 | {
74 | IFile file = wizardPage.createNewFile();
75 | if (file == null)
76 | return false;
77 |
78 | try
79 | {
80 | setNamespace(file, guessNamespace(file));
81 | new FormatProcessorXML().formatFile(file);
82 | }
83 | catch (Exception e)
84 | {
85 | Activator.log(Status.WARNING, e.getMessage(), e);
86 | }
87 | try
88 | {
89 | IDE.openEditor(workbench.getActiveWorkbenchWindow().getActivePage(), file);
90 | }
91 | catch (PartInitException e)
92 | {
93 | Activator.log(Status.ERROR, e.getMessage(), e);
94 | }
95 | return true;
96 | }
97 |
98 | private String guessNamespace(IFile file)
99 | {
100 | IProject project = file.getProject();
101 | IJavaProject javaProject = JavaCore.create(project);
102 | if (javaProject != null)
103 | {
104 | IPath fullPath = file.getFullPath();
105 | try
106 | {
107 | for (IClasspathEntry entry : javaProject.getRawClasspath())
108 | {
109 | if (entry.getPath().isPrefixOf(fullPath))
110 | {
111 | IPath relativePath = fullPath.makeRelativeTo(entry.getPath());
112 | return relativePath.removeFileExtension().toString().replace('/', '.');
113 | }
114 | }
115 | }
116 | catch (JavaModelException e)
117 | {
118 | Activator.log(Status.ERROR,
119 | "Failed to get raw classpath for project: " + javaProject.getElementName(), e);
120 | }
121 | }
122 | // empty string to raise warning
123 | return "";
124 | }
125 |
126 | private void setNamespace(IFile mapperFile, String namespace)
127 | throws IOException, CoreException
128 | {
129 | IStructuredModel model = StructuredModelManager.getModelManager()
130 | .getModelForEdit(mapperFile);
131 | if (model == null)
132 | return;
133 |
134 | try
135 | {
136 | model.beginRecording(this);
137 | model.aboutToChangeModel();
138 | if (model instanceof IDOMModel)
139 | {
140 | IDOMDocument mapperDoc = ((IDOMModel)model).getDocument();
141 | Element mapperNode = mapperDoc.getDocumentElement();
142 | mapperNode.setAttribute("namespace", namespace);
143 | }
144 | }
145 | finally
146 | {
147 | model.changedModel();
148 | if (!model.isSharedForEdit() && model.isSaveNeeded())
149 | {
150 | model.save();
151 | }
152 | model.endRecording(this);
153 | model.releaseFromEdit();
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/mybatipse/src/net/harawata/mybatipse/wizard/NewXmlMapperWizardPage.java:
--------------------------------------------------------------------------------
1 | /*-******************************************************************************
2 | * Copyright (c) 2016 Iwao AVE!.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Iwao AVE! - initial API and implementation and/or initial documentation
10 | *******************************************************************************/
11 |
12 | package net.harawata.mybatipse.wizard;
13 |
14 | import java.io.ByteArrayInputStream;
15 | import java.io.InputStream;
16 | import java.io.UnsupportedEncodingException;
17 |
18 | import org.eclipse.core.resources.IFile;
19 | import org.eclipse.jdt.core.IClassFile;
20 | import org.eclipse.jdt.core.ICompilationUnit;
21 | import org.eclipse.jdt.core.IJavaElement;
22 | import org.eclipse.jdt.core.IType;
23 | import org.eclipse.jface.viewers.IStructuredSelection;
24 | import org.eclipse.ui.dialogs.WizardNewFileCreationPage;
25 |
26 | /**
27 | * @author Iwao AVE!
28 | */
29 | public class NewXmlMapperWizardPage extends WizardNewFileCreationPage
30 | {
31 | private static final String EXT = "xml";
32 |
33 | public NewXmlMapperWizardPage(IStructuredSelection selection)
34 | {
35 | super("NewXmlMapperWizardPage", selection);
36 | setTitle("New MyBatis XML Mapper");
37 | setDescription("Create a new MyBatis XML Mapper file.");
38 | setFileExtension(EXT);
39 | // Propose file name
40 | Object elem = selection.getFirstElement();
41 | if (elem != null)
42 | {
43 | if (elem instanceof IJavaElement)
44 | {
45 | int javaElemType = ((IJavaElement)elem).getElementType();
46 | if (javaElemType == IJavaElement.COMPILATION_UNIT)
47 | {
48 | setFileNameWithExtension(((ICompilationUnit)elem).getElementName());
49 | }
50 | else if (javaElemType == IJavaElement.CLASS_FILE)
51 | {
52 | setFileNameWithExtension(((IClassFile)elem).getElementName());
53 | }
54 | else if (javaElemType == IJavaElement.TYPE)
55 | {
56 | setFileNameWithExtension(((IType)elem).getElementName());
57 | }
58 | }
59 | else if (elem instanceof IFile)
60 | {
61 | setFileNameWithExtension(
62 | ((IFile)elem).getFullPath().removeFileExtension().lastSegment());
63 | }
64 | else
65 | {
66 | // Leave empty.
67 | }
68 | }
69 | }
70 |
71 | private void setFileNameWithExtension(String name)
72 | {
73 | setFileName(name + "." + EXT);
74 | }
75 |
76 | @Override
77 | protected InputStream getInitialContents()
78 | {
79 | StringBuilder buffer = new StringBuilder();
80 | buffer.append("\n")
81 | .append(
82 | "\n")
83 | .append("\n")
84 | .append("");
85 | try
86 | {
87 | return new ByteArrayInputStream(buffer.toString().getBytes("utf-8"));
88 | }
89 | catch (UnsupportedEncodingException e)
90 | {
91 | return null;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/screen/ac-class-cc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-class-cc.png
--------------------------------------------------------------------------------
/screen/ac-class.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-class.png
--------------------------------------------------------------------------------
/screen/ac-jdbc-type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-jdbc-type.png
--------------------------------------------------------------------------------
/screen/ac-ns1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-ns1.png
--------------------------------------------------------------------------------
/screen/ac-ns2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-ns2.png
--------------------------------------------------------------------------------
/screen/ac-options-keyprop-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-options-keyprop-java.png
--------------------------------------------------------------------------------
/screen/ac-prop-test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-prop-test.png
--------------------------------------------------------------------------------
/screen/ac-prop1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-prop1.png
--------------------------------------------------------------------------------
/screen/ac-prop2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-prop2.png
--------------------------------------------------------------------------------
/screen/ac-ref.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-ref.png
--------------------------------------------------------------------------------
/screen/ac-result-prop-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-result-prop-java.png
--------------------------------------------------------------------------------
/screen/ac-results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-results.png
--------------------------------------------------------------------------------
/screen/ac-rmap-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-rmap-java.png
--------------------------------------------------------------------------------
/screen/ac-select-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-select-java.png
--------------------------------------------------------------------------------
/screen/ac-selkey-keyprop-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-selkey-keyprop-java.png
--------------------------------------------------------------------------------
/screen/ac-setting-name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-setting-name.png
--------------------------------------------------------------------------------
/screen/ac-setting-value.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-setting-value.png
--------------------------------------------------------------------------------
/screen/ac-stmt-prop-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-stmt-prop-java.png
--------------------------------------------------------------------------------
/screen/ac-stmt-prop-xml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-stmt-prop-xml.png
--------------------------------------------------------------------------------
/screen/ac-stmt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/ac-stmt.png
--------------------------------------------------------------------------------
/screen/actual-parameters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/actual-parameters.png
--------------------------------------------------------------------------------
/screen/err-refid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/err-refid.png
--------------------------------------------------------------------------------
/screen/hl-java-method.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/hl-java-method.png
--------------------------------------------------------------------------------
/screen/hl-refid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/hl-refid.png
--------------------------------------------------------------------------------
/screen/hl-xml-mapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/hl-xml-mapper.png
--------------------------------------------------------------------------------
/screen/hl-xml-statement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/hl-xml-statement.png
--------------------------------------------------------------------------------
/screen/nature.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/nature.png
--------------------------------------------------------------------------------
/screen/prblm-view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/prblm-view.png
--------------------------------------------------------------------------------
/screen/pref-alias.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/pref-alias.png
--------------------------------------------------------------------------------
/screen/qa-add-param1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/qa-add-param1.png
--------------------------------------------------------------------------------
/screen/qa-add-param2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/qa-add-param2.png
--------------------------------------------------------------------------------
/screen/qa-copy-statement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/qa-copy-statement.png
--------------------------------------------------------------------------------
/screen/qa-move-resultmap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/qa-move-resultmap.png
--------------------------------------------------------------------------------
/screen/qa-move-statement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/qa-move-statement.png
--------------------------------------------------------------------------------
/screen/refactor-rename-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/refactor-rename-java.png
--------------------------------------------------------------------------------
/screen/refactor-rename-xml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/refactor-rename-xml.png
--------------------------------------------------------------------------------
/screen/smart-copy-console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/smart-copy-console.png
--------------------------------------------------------------------------------
/screen/sqlview-xml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/sqlview-xml.png
--------------------------------------------------------------------------------
/screen/sqlview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/sqlview.png
--------------------------------------------------------------------------------
/screen/wizard-xml-mapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/wizard-xml-mapper.png
--------------------------------------------------------------------------------
/screen/xml-proposal-order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/mybatipse/234a649cd4deccd5897b143250a59a370d872bda/screen/xml-proposal-order.png
--------------------------------------------------------------------------------