/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ext.oracle.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.core.DBeaverUI;
import org.jkiss.dbeaver.ext.oracle.model.OraclePackage;
import org.jkiss.dbeaver.ext.oracle.model.OracleProcedureArgument;
import org.jkiss.dbeaver.ext.oracle.model.OracleProcedurePackaged;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameterKind;
import org.jkiss.dbeaver.ui.actions.navigator.NavigatorHandlerObjectOpen;
import org.jkiss.dbeaver.ui.editors.entity.EntityEditor;
import org.jkiss.dbeaver.ui.editors.sql.SQLEditorBase;
import org.jkiss.dbeaver.ui.editors.sql.SQLEditorNested;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class PackageNavigateHandler extends AbstractHandler //implements IElementUpdater
{
private static final Log log = Log.getLog(PackageNavigateHandler.class);
public PackageNavigateHandler() {
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException
{
final OracleProcedurePackaged procedure = getSelectedProcedure(event);
if (procedure != null) {
OraclePackage procPackage = procedure.getParentObject();
IEditorPart entityEditor = NavigatorHandlerObjectOpen.openEntityEditor(procPackage);
if (entityEditor instanceof EntityEditor) {
((EntityEditor) entityEditor).switchFolder("source.definition");
SQLEditorBase sqlEditor = entityEditor.getAdapter(SQLEditorBase.class);
if (sqlEditor != null) {
new NavigateJob(procedure, sqlEditor).schedule();
}
}
}
return null;
}
static class NavigateJob extends AbstractJob {
private final OracleProcedurePackaged procedure;
private final SQLEditorBase sqlEditor;
public NavigateJob(OracleProcedurePackaged procedure, SQLEditorBase sqlEditor) {
super("Navigate procedure '" + procedure.getFullyQualifiedName(DBPEvaluationContext.UI));
this.procedure = procedure;
this.sqlEditor = sqlEditor;
}
@Override
protected IStatus run(DBRProgressMonitor monitor) {
try {
navigate(monitor);
} catch (InterruptedException e) {
return Status.CANCEL_STATUS;
} catch (DBException e) {
return GeneralUtils.makeExceptionStatus(e);
}
return Status.OK_STATUS;
}
private void navigate(DBRProgressMonitor monitor) throws InterruptedException, DBException {
if (sqlEditor instanceof SQLEditorNested) {
int checkAttempts = 0;
while (!((SQLEditorNested) sqlEditor).isDocumentLoaded() && checkAttempts < 10) {
Thread.sleep(500);
checkAttempts++;
}
}
final Document document = sqlEditor.getDocument();
if (document != null) {
String procRegex = procedure.getProcedureType().name() + "\\s+" + procedure.getName();
final Collection<OracleProcedureArgument> parameters = procedure.getParameters(monitor);
if (parameters != null) {
List<OracleProcedureArgument> inParams = new ArrayList<>();
for (OracleProcedureArgument arg : parameters) {
if (arg.getParameterKind() != DBSProcedureParameterKind.OUT && !arg.isResultArgument()) {
inParams.add(arg);
}
}
if (!inParams.isEmpty()) {
procRegex += "\\s*\\([^\\)]+\\)";
}
}
final FindReplaceDocumentAdapter findAdapter = new FindReplaceDocumentAdapter(document);
try {
final IRegion procRegion = findAdapter.find(0, procRegex, true, false, false, true);
if (procRegion != null) {
DBeaverUI.asyncExec(new Runnable() {
@Override
public void run() {
sqlEditor.selectAndReveal(procRegion.getOffset(), procRegion.getLength());
}
});
}
} catch (BadLocationException e) {
log.error("Error finding procedure source", e);
}
}
}
}
private OracleProcedurePackaged getSelectedProcedure(ExecutionEvent event)
{
final ISelection currentSelection = HandlerUtil.getCurrentSelection(event);
if (currentSelection instanceof IStructuredSelection && !currentSelection.isEmpty()) {
Object firstElement = ((IStructuredSelection) currentSelection).getFirstElement();
return RuntimeUtils.getObjectAdapter(firstElement, OracleProcedurePackaged.class);
}
return null;
}
/*
@Override
public void updateElement(UIElement element, Map parameters)
{
List<OracleSourceObject> objects = new ArrayList<>();
IWorkbenchPartSite partSite = UIUtils.getWorkbenchPartSite(element.getServiceLocator());
if (partSite != null) {
final ISelectionProvider selectionProvider = partSite.getSelectionProvider();
if (selectionProvider != null) {
ISelection selection = selectionProvider.getSelection();
if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
for (Iterator<?> iter = ((IStructuredSelection) selection).iterator(); iter.hasNext(); ) {
final Object item = iter.next();
final OracleSourceObject sourceObject = RuntimeUtils.getObjectAdapter(item, OracleSourceObject.class);
if (sourceObject != null) {
objects.add(sourceObject);
}
}
}
}
if (objects.isEmpty()) {
final IWorkbenchPart activePart = partSite.getPart();
final OracleSourceObject sourceObject = RuntimeUtils.getObjectAdapter(activePart, OracleSourceObject.class);
if (sourceObject != null) {
objects.add(sourceObject);
}
}
}
if (!objects.isEmpty()) {
if (objects.size() > 1) {
element.setText("Compile " + objects.size() + " objects");
} else {
final OracleSourceObject sourceObject = objects.get(0);
String objectType = TextUtils.formatWord(sourceObject.getSourceType().name());
element.setText("Compile " + objectType*/
/* + " '" + sourceObject.getName() + "'"*//*
);
}
}
}
public static boolean compileUnit(DBRProgressMonitor monitor, DBCCompileLog compileLog, OracleSourceObject unit) throws DBCException
{
final DBEPersistAction[] compileActions = unit.getCompileActions();
if (ArrayUtils.isEmpty(compileActions)) {
return true;
}
try (JDBCSession session = DBUtils.openUtilSession(monitor, unit.getDataSource(), "Compile '" + unit.getName() + "'")) {
boolean success = true;
for (DBEPersistAction action : compileActions) {
final String script = action.getScript();
compileLog.trace(script);
if (monitor.isCanceled()) {
break;
}
try {
try (DBCStatement dbStat = session.prepareStatement(
DBCStatementType.QUERY,
script,
false, false, false))
{
dbStat.executeStatement();
}
action.handleExecute(session, null);
} catch (DBCException e) {
action.handleExecute(session, e);
throw e;
}
if (action instanceof OracleObjectPersistAction) {
if (!logObjectErrors(session, compileLog, unit, ((OracleObjectPersistAction) action).getObjectType())) {
success = false;
}
}
}
final DBSObjectState oldState = unit.getObjectState();
unit.refreshObjectState(monitor);
if (unit.getObjectState() != oldState) {
unit.getDataSource().getContainer().fireEvent(new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, unit));
}
return success;
}
}
public static boolean logObjectErrors(
JDBCSession session,
DBCCompileLog compileLog,
OracleSourceObject unit,
OracleObjectType objectType)
{
try {
try (JDBCPreparedStatement dbStat = session.prepareStatement(
"SELECT * FROM SYS.ALL_ERRORS WHERE OWNER=? AND NAME=? AND TYPE=? ORDER BY SEQUENCE")) {
dbStat.setString(1, unit.getSchema().getName());
dbStat.setString(2, unit.getName());
dbStat.setString(3, objectType.getTypeName());
try (ResultSet dbResult = dbStat.executeQuery()) {
boolean hasErrors = false;
while (dbResult.next()) {
DBCCompileError error = new DBCCompileError(
"ERROR".equals(dbResult.getString("ATTRIBUTE")),
dbResult.getString("TEXT"),
dbResult.getInt("LINE"),
dbResult.getInt("POSITION"));
hasErrors = true;
if (error.isError()) {
compileLog.error(error);
} else {
compileLog.warn(error);
}
}
return !hasErrors;
}
}
} catch (Exception e) {
log.error("Can't read user errors", e);
return false;
}
}
*/
}